diff --git a/resources/[housing]/brutal_housing/config.lua b/resources/[housing]/brutal_housing/config.lua index eaab6bdfa..5917b0e42 100644 --- a/resources/[housing]/brutal_housing/config.lua +++ b/resources/[housing]/brutal_housing/config.lua @@ -13,7 +13,7 @@ Config = { Core = 'QBCORE', -- 'ESX' / 'QBCORE' | Other core setting on the 'core' folder. VoiceSytem = 'yaca-voice', -- "pma-voice" / "mumble" / "SaltyChat" Inventory = 'qb_inventory_new', -- 'ox_inventory' / 'qb_inventory_old'/ 'qb_inventory_new' / 'quasar_inventory' / 'chezza_inventory' / 'codem_inventory' / 'core_inventory' // Custom can be add in the cl_utils.lua!!! - Wardrobe = 'default', -- 'default' / 'ak47_clothing' / 'codem_apperance' / 'fivem_appearance' / 'illenium_appearance' / 'qb_clothing' / 'raid_clothes' / 'rcore_clothes' / 'rcore_clothing' / 'sleek_clothestore' / 'tgiann_clothing' // Custom can be add in the cl_utils.lua!!! + Wardrobe = 'illenium_appearance', -- 'default' / 'ak47_clothing' / 'codem_apperance' / 'fivem_appearance' / 'illenium_appearance' / 'qb_clothing' / 'raid_clothes' / 'rcore_clothes' / 'rcore_clothing' / 'sleek_clothestore' / 'tgiann_clothing' // Custom can be add in the cl_utils.lua!!! TextUI = 'ox_lib', -- false / 'brutal_textui' / 'ox_lib' / 'okokTextUI' / 'ESXTextUI' / 'QBDrawText' // Custom can be add in the cl_utils.lua!!! BrutalKeys = false, -- Buy here: https://store.brutalscripts.com BrutalPoliceJob = false, -- Buy here: https://store.brutalscripts.com | Better connection @@ -36,14 +36,14 @@ Config = { Blips = { available = true, - availableHouse = {label = "Available House", size = 0.7, sprite = 40, color = 2}, - availableGarage = {label = "Available Garage", size = 0.7, sprite = 357, color = 2}, + availableHouse = {label = "Kaufbares Haus", size = 0.7, sprite = 40, color = 2}, + availableGarage = {label = "Kaufbare Garage", size = 0.7, sprite = 357, color = 2}, owned = true, - myHouse = {label = "My House", size = 0.7, sprite = 40, color = 53}, - myGarage = {label = "My Garage", size = 0.7, sprite = 357, color = 53}, - hasKeyHouse = {label = "House", size = 0.7, sprite = 40, color = 53}, - hasKeyGarage = {label = "House", size = 0.7, sprite = 40, color = 53}, - ownedHouse = {label = "House", size = 0.7, sprite = 40, color = 1}, + myHouse = {label = "Mein Haus", size = 0.7, sprite = 40, color = 53}, + myGarage = {label = "Meine Garage", size = 0.7, sprite = 357, color = 53}, + hasKeyHouse = {label = "Haus", size = 0.7, sprite = 40, color = 53}, + hasKeyGarage = {label = "Haus", size = 0.7, sprite = 40, color = 53}, + ownedHouse = {label = "Haus", size = 0.7, sprite = 40, color = 1}, ownedGarage = {label = "Garage", size = 0.7, sprite = 357, color = 1}, police = true, burglarAlarm = {label = "Einbruch Alarm", size = 1.0, sprite = 161, color = 1}, @@ -171,7 +171,7 @@ Config = { MyProperties = { Command = 'myproperties', Suggestion = 'To manage your propertys', - Control = '', -- Controls list: https://docs.fivem.net/docs/game-references/input-mapper-parameter-ids/keyboard/ + Control = 'F7', -- Controls list: https://docs.fivem.net/docs/game-references/input-mapper-parameter-ids/keyboard/ }, ServerDestroy = { diff --git a/resources/[housing]/brutal_keys/.fxap b/resources/[housing]/brutal_keys/.fxap new file mode 100644 index 000000000..8d12bf19c Binary files /dev/null and b/resources/[housing]/brutal_keys/.fxap differ diff --git a/resources/[housing]/brutal_keys/README.md b/resources/[housing]/brutal_keys/README.md new file mode 100644 index 000000000..cecf3b394 --- /dev/null +++ b/resources/[housing]/brutal_keys/README.md @@ -0,0 +1 @@ +Please follow the instructions: https://docs.brutalscripts.com \ No newline at end of file diff --git a/resources/[housing]/brutal_keys/cl_utils.lua b/resources/[housing]/brutal_keys/cl_utils.lua new file mode 100644 index 000000000..36b8ece68 --- /dev/null +++ b/resources/[housing]/brutal_keys/cl_utils.lua @@ -0,0 +1,85 @@ +ESX = Core +QBCore = Core + +-- Buy here: (4€+VAT) https://store.brutalscripts.com +function notification(title, text, time, type) + if Config.BrutalNotify then + exports['brutal_notify']:SendAlert(title, text, time, type) + else + -- Put here your own notify and set the Config.BrutalNotify to false + SetNotificationTextEntry("STRING") + AddTextComponentString(text) + DrawNotification(0,1) + + -- Default ESX Notify: + --TriggerEvent('esx:showNotification', text) + + -- Default QB Notify: + --TriggerEvent('QBCore:Notify', text, 'info', 5000) + + -- OKOK Notify: + -- exports['okokNotify']:Alert(title, text, time, type, false) + + end +end + +function TextUIFunction(type, text) + if type == 'open' then + if Config.TextUI:lower() == 'ox_lib' then + lib.showTextUI(text) + elseif Config.TextUI:lower() == 'okoktextui' then + exports['okokTextUI']:Open(text, 'darkblue', 'right') + elseif Config.TextUI:lower() == 'esxtextui' then + ESX.TextUI(text) + elseif Config.TextUI:lower() == 'qbdrawtext' then + exports['qb-core']:DrawText(text,'left') + elseif Config.TextUI:lower() == 'brutal_textui' then + exports['brutal_textui']:Open(text, "blue") + end + elseif type == 'hide' then + if Config.TextUI:lower() == 'ox_lib' then + lib.hideTextUI() + elseif Config.TextUI:lower() == 'okoktextui' then + exports['okokTextUI']:Close() + elseif Config.TextUI:lower() == 'esxtextui' then + ESX.HideUI() + elseif Config.TextUI:lower() == 'qbdrawtext' then + exports['qb-core']:HideText() + elseif Config.TextUI:lower() == 'brutal_textui' then + exports['brutal_textui']:Close() + end + end +end + +function PoliceAlert(coords, plate) + local x,y,z = table.unpack(coords) + local streetLabel = GetStreetNameFromHashKey(GetStreetNameAtCoord(x,y,z)) + + if GetResourceState("brutal_policejob") == "started" then + TriggerServerEvent('brutal_policejob:server:citizencall', 'create', "Vehicle jacking", coords, streetLabel) + end +end + +function OpenMenuUtil() + InMenu = true + SetNuiFocus(true, true) + + Citizen.CreateThread(function() + while InMenu do + N_0xf4f2c0d4ee209e20() -- it's disable the AFK camera zoom + Citizen.Wait(15000) + end + end) + + DisplayRadar(false) +end + +function DisableMinimap() + DisplayRadar(false) + -- Here you can add a trigger to hide your HUD system +end + +function EnableMinimap() + DisplayRadar(true) + -- Here you can add a trigger to enable your HUD system +end \ No newline at end of file diff --git a/resources/[housing]/brutal_keys/client/client.lua b/resources/[housing]/brutal_keys/client/client.lua new file mode 100644 index 000000000..863584375 Binary files /dev/null and b/resources/[housing]/brutal_keys/client/client.lua differ diff --git a/resources/[housing]/brutal_keys/client/desktop.ini b/resources/[housing]/brutal_keys/client/desktop.ini new file mode 100644 index 000000000..704fc3d2f Binary files /dev/null and b/resources/[housing]/brutal_keys/client/desktop.ini differ diff --git a/resources/[housing]/brutal_keys/client/nui.lua b/resources/[housing]/brutal_keys/client/nui.lua new file mode 100644 index 000000000..92491eac1 Binary files /dev/null and b/resources/[housing]/brutal_keys/client/nui.lua differ diff --git a/resources/[housing]/brutal_keys/config.lua b/resources/[housing]/brutal_keys/config.lua new file mode 100644 index 000000000..df0eaaedd --- /dev/null +++ b/resources/[housing]/brutal_keys/config.lua @@ -0,0 +1,155 @@ +---------------------------------------------------------------------------------------------- +--------------------------------------| BRUTAL KEYS :) |-------------------------------------- +---------------------------------------------------------------------------------------------- + +--[[ +Hi, thank you for buying our script, We are very grateful! + +For help join our Discord server: https://discord.gg/85u2u5c8q9 +More informations about the script: https://docs.brutalscripts.com +--]] + +Config = { + Core = 'QBCORE', -- 'ESX' / 'QBCORE' | Other core setting on the 'core' folder. + TextUI = 'ox_lib', -- false / 'brutal_textui' / 'ox_lib' / 'okokTextUI' / 'ESXTextUI' / 'QBDrawText' // Custom can be add in the cl_utils.lua!!! + BrutalNotify = true, -- Buy here: (4€+VAT) https://store.brutalscripts.com | Or set up your own notify >> cl_utils.lua + AdminGroups = {'superadmin', 'admin', 'mod', 'god'}, -- Admin groups + + DataStorage = { + --[[ + optimized = Saves the data when the script is restarted, the server is shut down or restarted, or during a scheduled server restart. + events: "txAdmin:events:serverShuttingDown" & "txAdmin:events:scheduledRestart" or fixed restart times. + resource_heavy = all data will be saved immediately, this is very stressful for the server so we don't recommend using this, but the choice is up to you. + ]]-- + + Type = "optimized", -- "optimized" / "resource_heavy" + Restarts = {}, -- example: "11:59" | Save the data 1 minute before restart. Save data at 15:59 instead of 16:00 + }, + + CopyPrice = 500, -- Key copy price + UseVehicleKeySystem = false, -- true / false | false = the full vehicle key system is switched off. + DriveWithKey = true, -- If true, players can only drive the car if they have a key, IF false, they can drive the car anytime they find it unlocked. + LockPicking = {maxTry = 1, item = "lockpick"}, -- maxTry = maximum try per vehicle | item = item or "" + Hotwiring = {maxTry = 1, successrate = 25, item = "screwdriver"}, -- maxTry = maximum try per vehicle | successrate = 10 = 10% | item = item or "" + AlertPolice = {use = true, chance = 10}, -- chance 10 = 10% | Supports Brutal Policejob basically to modity it open the cl_utils.lua file + UseKeyProp = true, -- Use the key prop in the player's hand when closing or opening a vehicle + LostVehicleKeys = { + npc = vector4(-354.5593, -128.0446, 39.4307, 65.9746), -- npc VECTOR4! coords + model = "ig_benny", -- npc type + blip = {use = true, label = "Lost Vehicle Keys", size = 1.0, sprite = 186, color = 1}, + price = 2500 -- if they lost all of their keys then the price is higher + }, + + QuickKeys = { + ['everyone'] = { -- no one needs a key to drive those vehicles + "adder", "bmx" + }, + + ['police'] = { -- player in the job do not need a key to drive the vehicle + "police", "police2", "police3", "policeb", "pbus" + }, + + ['ambulance'] = { -- player in the job do not need a key to drive the vehicle + "ambulance", + }, + }, + + Commands = { + MyKeys = { + Command = 'mykeys', + Suggestion = 'To manage your keys', + Control = '', -- Controls list: https://docs.fivem.net/docs/game-references/input-mapper-parameter-ids/keyboard/ + }, + + VehicleKey = { + Command = 'vkey', + Suggestion = 'To open the nearest vehicle', + Control = '', -- 'G' | Controls list: https://docs.fivem.net/docs/game-references/input-mapper-parameter-ids/keyboard/ + }, + + Lockpicking = { + Command = 'lockpick', + Suggestion = 'Lockpicking the nearest vehicle', + Control = '', -- Controls list: https://docs.fivem.net/docs/game-references/input-mapper-parameter-ids/keyboard/ + }, + + Hotwiring = { + Command = 'hotwiring', + Suggestion = 'To start the vehicle without keys', + Control = '', -- Controls list: https://docs.fivem.net/docs/game-references/input-mapper-parameter-ids/keyboard/ + }, + + -- Admin -- + + StaffMode = { + Command = 'kstaff', + Suggestion = 'To switch Key System Staff mode ON/OFF', + }, + + AddKey = { -- /addkey [ID] [KEY-ID] [label] + Command = 'addkey', + Suggestion = 'To add key', + }, + + RemoveKey = { -- /removekey [ID] [KEY-ID] + Command = 'removekey', + Suggestion = 'To remove key', + }, + + AddVehicleKey = { -- /addvehiclekey [ID] [PLATE] + Command = 'addvehiclekey', + Suggestion = 'To add vehicle key', + }, + + AddVehicleTemporaryKey = { -- /addtempkey [ID] [PLATE] + Command = 'addtempkey', + Suggestion = 'To add vehicle temporary key', + }, + + RemoveVehicleKey = { -- /removevehiclekey [ID] [PLATE] + Command = 'removevehiclekey', + Suggestion = 'To remove vehicle key', + }, + }, + + ----------------------------------------------------------- + -----------------------| TRANSLATE |----------------------- + ----------------------------------------------------------- + + NUILanguage = "en", -- "en", "es", "fr", "de", "pt", "it", "pl", "nl", "ru", "tr", "hu", "ro", "cs", "sv", "ar" + + MoneyForm = '$', -- Money form + + Texts = { + [1] = {'[E] - Lost Key', 38, 'Open the lost key menu'}, + }, + + -- Notify function EDITABLE >> cl_utils.lua + Notify = { + [1] = {"Keys", "Staff mode: ON", 5000, "success"}, + [2] = {"Keys", "Staff mode: OFF", 5000, "error"}, + [3] = {"Keys", "You got a new key!", 5000, "info"}, + [4] = {"Keys", "A key has been deleted!", 5000, "success"}, + [5] = {"Keys", "You gave them a key:", 5000, "info"}, + [6] = {"Keys", "You copied a key!", 5000, "success"}, + [7] = {"Keys", "You got a key from:", 5000, "info"}, + [8] = {"Keys", "Successful lock change!", 5000, "success"}, + [9] = {"Keys", "Only the vehicle owner can change!", 5000, "error"}, + [10] = {"Keys", "You don't have enough money!", 5000, "error"}, + [11] = {"Keys", "You have no car / you have keys to all your cars!", 5000, "error"}, + [12] = {"Keys", "No vehicle near you!", 5000, "error"}, + [13] = {"Keys", "The vehicle is open!", 5000, "error"}, + [14] = {"Keys", "Someone is sitting in the car!", 5000, "error"}, + [15] = {"Keys", "You have reached the maximum amount of keys!", 5000, "error"}, + [16] = {"Keys", "This person already has a temporary key for this car!", 5000, "error"}, + [17] = {"Keys", "To reduce the server load, you will have to wait a little!", 5000, "error"}, + [18] = {"Keys", "Plate: 3-8 characters", 5000, "error"}, + [19] = {"Keys", "Invalid Player ID!", 5000, "error"}, + [20] = {"Keys", "You can't try again!", 5000, "error"}, + [21] = {"Keys", "You have to sit in the driver's seat!", 5000, "error"}, + [22] = {"Keys", "You did it! You've started the engine!", 5000, "success"}, + [23] = {"Keys", "Unfortunately the safety lock would not let you start the engine!", 5000, "error"}, + [24] = {"Keys", "You need: Lockpick", 5000, "error"}, + [25] = {"Keys", "You need: Screwdriver", 5000, "error"}, + }, +} \ No newline at end of file diff --git a/resources/[housing]/brutal_keys/core/client-core.lua b/resources/[housing]/brutal_keys/core/client-core.lua new file mode 100644 index 000000000..939af1c6b --- /dev/null +++ b/resources/[housing]/brutal_keys/core/client-core.lua @@ -0,0 +1,68 @@ +Core = nil + +if Config['Core']:upper() == 'ESX' then + local _esx_ = 'new' -- 'new' / 'old' + + if _esx_ then + Core = exports['es_extended']:getSharedObject() + else + while Core == nil do + TriggerEvent('esx:getSharedObject', function(obj) Core = obj end) + Citizen.Wait(0) + end + end + + LoadedEvent = 'esx:playerLoaded' + ReviveEvent = 'esx_ambulancejob:revive' + JobUpdateEvent = 'esx:setJob' + TSCB = Core.TriggerServerCallback + + function GetPlayerJobDatas() + return Core.GetPlayerData().job + end + + function GetPlayersFunction() + return Core.Game.GetPlayers() + end + + function GetVehiclePropertiesFunction(vehicle) + return Core.Game.GetVehicleProperties(vehicle) + end + + function SetVehiclePropertiesFunction(vehicle, properties) + return Core.Game.SetVehicleProperties(vehicle, properties) + end + + function GetClosestVehicleFunction(coords, modelFilter) + return Core.Game.GetClosestVehicle(coords, modelFilter) + end + +elseif Config['Core']:upper() == 'QBCORE' then + Core = exports['qb-core']:GetCoreObject() + + LoadedEvent = 'QBCore:Client:OnPlayerLoaded' + ReviveEvent = 'hospital:client:Revive' + JobUpdateEvent = 'QBCore:Client:OnJobUpdate' + TSCB = Core.Functions.TriggerCallback + + function GetPlayerJobDatas() + return Core.Functions.GetPlayerData().job + end + + function GetPlayersFunction() + return Core.Functions.GetPlayers() + end + + function GetVehiclePropertiesFunction(vehicle) + return Core.Functions.GetVehicleProperties(vehicle) + end + + function SetVehiclePropertiesFunction(vehicle, properties) + return Core.Functions.SetVehicleProperties(vehicle, properties) + end + + function GetClosestVehicleFunction(coords, modelFilter) + return Core.Functions.GetClosestVehicle(coords, modelFilter) + end + +end \ No newline at end of file diff --git a/resources/[housing]/brutal_keys/core/desktop.ini b/resources/[housing]/brutal_keys/core/desktop.ini new file mode 100644 index 000000000..704fc3d2f Binary files /dev/null and b/resources/[housing]/brutal_keys/core/desktop.ini differ diff --git a/resources/[housing]/brutal_keys/core/server-core.lua b/resources/[housing]/brutal_keys/core/server-core.lua new file mode 100644 index 000000000..51c04ff5f --- /dev/null +++ b/resources/[housing]/brutal_keys/core/server-core.lua @@ -0,0 +1,271 @@ +Core = nil + +if Config['Core']:upper() == 'ESX' then + local _esx_ = 'new' -- 'new' / 'old' + + if _esx_ == 'new' then + Core = exports['es_extended']:getSharedObject() + else + Core = nil + TriggerEvent('esx:getSharedObject', function(obj) Core = obj end) + while Core == nil do + Citizen.Wait(0) + end + end + + RESCB = Core.RegisterServerCallback + GETPFI = Core.GetPlayerFromId + RUI = Core.RegisterUsableItem + SetJobEvent = 'esx:setJob' + onPlayerDeath = 'esx:onPlayerDeath' + SQLData = { + player_vehicles = 'owned_vehicles', + } + + function GetIdentifier(source) + local xPlayer = GETPFI(source) + while xPlayer == nil do + Citizen.Wait(1000) + xPlayer = GETPFI(source) + end + return xPlayer.identifier + end + + function GetPlayerByIdentifier(identifier) + return Core.GetPlayerFromIdentifier(identifier) + end + + function GetAccountMoney(source,account) + local xPlayer = GETPFI(source) + if account == 'bank' then + return xPlayer.getAccount(account).money + elseif account == 'money' then + return xPlayer.getMoney() + end + end + + function AddMoneyFunction(source, account, amount) + local xPlayer = GETPFI(source) + if account == 'bank' then + xPlayer.addAccountMoney('bank', amount) + elseif account == 'money' then + xPlayer.addMoney(amount) + end + end + + function RemoveAccountMoney(source, account, amount) + local xPlayer = GETPFI(source) + if account == 'bank' then + xPlayer.removeAccountMoney('bank', amount) + elseif account == 'money' then + xPlayer.removeMoney(amount) + end + end + + function GetItemCount(source, item) + local xPlayer = GETPFI(source) + + if _esx_ == 'new' then + return xPlayer.getInventoryItem(item).count + else + if string.sub(item, 0, 6):lower() == 'weapon' then + local loadoutNum, weapon = xPlayer.getWeapon(item:upper()) + + if weapon then + return true + else + return false + end + else + return xPlayer.getInventoryItem(item).count + end + end + end + + function RemoveItem(source, item, amount) + local xPlayer = GETPFI(source) + if _esx_ == 'new' then + xPlayer.removeInventoryItem(item, amount) + else + if string.sub(item, 0, 6):lower() == 'weapon' then + xPlayer.removeWeapon(item) + else + xPlayer.removeInventoryItem(item, amount) + end + end + end + + function AddItem(source, item, count, info) + local xPlayer = GETPFI(source) + if _esx_ == 'new' then + xPlayer.addInventoryItem(item, count, info) + else + if string.sub(item, 0, 6):lower() == 'weapon' then + xPlayer.addWeapon(item, 90) + else + xPlayer.addInventoryItem(item, count) + end + end + end + + function GetPlayerNameFunction(source) + local name + if Config.SteamName then + name = GetPlayerName(source) or 'No Data' + else + local xPlayer = GETPFI(source) + name = xPlayer.getName() or 'No Data' + end + return name + end + + function GetPlayerJob(source) + local xPlayer = GETPFI(source) + return xPlayer.job.name + end + + function CreateCoreJob(name, label, grades) + Core.CreateJob(name, label, grades) + end + + function SetCoreJob(source, job, grade) + local xPlayer = GETPFI(source) + xPlayer.setJob(job, grade) + end + + function SetCoreJobOffline(identifier, job, grade) + MySQL.update('UPDATE users SET job = ?, job_grade = ? WHERE identifier = ?', {job, grade, identifier}) + end + + function GetPlayersFunction() + return Core.GetPlayers() + end + +elseif Config['Core']:upper() == 'QBCORE' then + + Core = exports['qb-core']:GetCoreObject() + + RESCB = Core.Functions.CreateCallback + GETPFI = Core.Functions.GetPlayer + RUI = Core.Functions.CreateUseableItem + SetJobEvent = 'QBCore:Server:SetGang' + onPlayerDeath = GetResourceState("brutal_ambulancejob") == "started" and 'onPlayerDeath' or 'hospital:server:SetDeathStatus' + SQLData = { + player_vehicles = 'player_vehicles', + } + + function GetIdentifier(source) + local xPlayer = GETPFI(source) + while xPlayer == nil do + Citizen.Wait(1000) + xPlayer = GETPFI(source) + end + return xPlayer.PlayerData.citizenid + end + + function GetPlayerByIdentifier(identifier) + return Core.Functions.GetPlayerByCitizenId(identifier) + end + + function GetAccountMoney(source, account) + local xPlayer = GETPFI(source) + if account == 'bank' then + return xPlayer.PlayerData.money.bank + elseif account == 'money' then + return xPlayer.PlayerData.money.cash + end + end + + function AddMoneyFunction(source, account, amount) + local xPlayer = GETPFI(source) + if account == 'bank' then + xPlayer.Functions.AddMoney('bank', amount) + elseif account == 'money' then + xPlayer.Functions.AddMoney('cash', amount) + end + end + + function RemoveAccountMoney(source, account, amount) + local xPlayer = GETPFI(source) + if account == 'bank' then + xPlayer.Functions.RemoveMoney('bank', amount) + elseif account == 'money' then + xPlayer.Functions.RemoveMoney('cash', amount) + end + end + + function GetItemCount(source, item) + local xPlayer = GETPFI(source) + local items = xPlayer.Functions.GetItemByName(item) + local item_count = 0 + if items ~= nil then + item_count = items.amount + else + item_count = 0 + end + return item_count + end + + function RemoveItem(source, item, amount) + local xPlayer = GETPFI(source) + xPlayer.Functions.RemoveItem(item, amount) + end + + function AddItem(source, item, count, info) + local xPlayer = GETPFI(source) + xPlayer.Functions.AddItem(item, count, nil, info) + end + + function GetPlayerNameFunction(source) + local name + if Config.SteamName then + name = GetPlayerName(source) + else + local xPlayer = GETPFI(source) + name = xPlayer.PlayerData.charinfo.firstname..' '..xPlayer.PlayerData.charinfo.lastname + end + return name + end + + function GetPlayerJob(source) + local xPlayer = GETPFI(source) + return xPlayer.PlayerData.gang.name + end + + function CreateCoreJob(name, label, grades) + Core.Functions.AddGang(name, + { + label = label, + grades = grades, + }) + end + + function UpdateCoreJob(name, label, grades) + Core.Functions.UpdateGang(name, { + label = label, + grades = grades, + }) + end + + function RemoveCoreJob(name) + Core.Functions.RemoveGang(name) + end + + function SetCoreJob(source, job, grade) + local xPlayer = GETPFI(source) + xPlayer.Functions.SetGang(job, grade) + end + + function SetCoreJobOffline(identifier, job) + local joblabel = "None" + if Gangs[job] ~= nil and Gangs[job].label ~= nil then + joblabel = Gangs[job].label + end + + MySQL.update('UPDATE players SET gang = ? WHERE citizenid = ?', {json.encode({grade = {level = 0, name = "Member"}, name = job, isboss = false, label = joblabel}), identifier}) + end + + function GetPlayersFunction() + return Core.Functions.GetPlayers() + end +end \ No newline at end of file diff --git a/resources/[housing]/brutal_keys/desktop.ini b/resources/[housing]/brutal_keys/desktop.ini new file mode 100644 index 000000000..704fc3d2f Binary files /dev/null and b/resources/[housing]/brutal_keys/desktop.ini differ diff --git a/resources/[housing]/brutal_keys/fxmanifest.lua b/resources/[housing]/brutal_keys/fxmanifest.lua new file mode 100644 index 000000000..7c3739d50 --- /dev/null +++ b/resources/[housing]/brutal_keys/fxmanifest.lua @@ -0,0 +1,61 @@ +fx_version 'cerulean' +games { 'gta5' } +lua54 'yes' + +author 'Keres & Dév' +description 'Brutal Keys - store.brutalscripts.com' +version '1.0.5' + +client_scripts { + 'config.lua', + 'core/client-core.lua', + 'cl_utils.lua', + 'client/*.lua' +} + +server_scripts { + '@mysql-async/lib/MySQL.lua', + 'config.lua', + 'core/server-core.lua', + 'sv_utils.lua', + 'server/*.lua', +} + +shared_script { + '@ox_lib/init.lua' +} + +export 'addKey' +export 'removeKey' +export 'addVehicleKey' +export 'addVehicleTemporaryKey' +export 'getPlayerKey' +export 'OpenKeysMenu' + + +ui_page "html/index.html" +files { + "html/index.html", + "html/style.css", + "html/script.js", + "html/assets/**", + 'locales/*.json', +} + +dependencies { + 'lockpick', -- https://github.com/baguscodestudio/lockpick + 'mx_fixwiring', -- https://github.com/mxlolshop/minigameFixWiring/tree/main/Fix%20Wiring/FiveM/mx_fixwiring + '/server:5181', -- ⚠️PLEASE READ⚠️; Requires at least SERVER build 5181 + '/gameBuild:2189', -- ⚠️PLEASE READ⚠️; Requires at least GAME build 2189. +} + +escrow_ignore { + 'config.lua', + 'cl_utils.lua', + 'sv_utils.lua', + 'core/client-core.lua', + 'core/server-core.lua', + 'stream/*.ydr', + 'stream/*.ytyp', +} +dependency '/assetpacks' \ No newline at end of file diff --git a/resources/[housing]/brutal_keys/html/assets/basic_key.svg b/resources/[housing]/brutal_keys/html/assets/basic_key.svg new file mode 100644 index 000000000..fe41699d1 --- /dev/null +++ b/resources/[housing]/brutal_keys/html/assets/basic_key.svg @@ -0,0 +1,3 @@ + + + diff --git a/resources/[housing]/brutal_keys/html/assets/basic_vehicle.svg b/resources/[housing]/brutal_keys/html/assets/basic_vehicle.svg new file mode 100644 index 000000000..78b06cb77 --- /dev/null +++ b/resources/[housing]/brutal_keys/html/assets/basic_vehicle.svg @@ -0,0 +1,3 @@ + + + diff --git a/resources/[housing]/brutal_keys/html/assets/bin.png b/resources/[housing]/brutal_keys/html/assets/bin.png new file mode 100644 index 000000000..57b59d38c Binary files /dev/null and b/resources/[housing]/brutal_keys/html/assets/bin.png differ diff --git a/resources/[housing]/brutal_keys/html/assets/desktop.ini b/resources/[housing]/brutal_keys/html/assets/desktop.ini new file mode 100644 index 000000000..704fc3d2f Binary files /dev/null and b/resources/[housing]/brutal_keys/html/assets/desktop.ini differ diff --git a/resources/[housing]/brutal_keys/html/assets/door_line.svg b/resources/[housing]/brutal_keys/html/assets/door_line.svg new file mode 100644 index 000000000..7759b567d --- /dev/null +++ b/resources/[housing]/brutal_keys/html/assets/door_line.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/resources/[housing]/brutal_keys/html/assets/key.svg b/resources/[housing]/brutal_keys/html/assets/key.svg new file mode 100644 index 000000000..4b8d54f3d --- /dev/null +++ b/resources/[housing]/brutal_keys/html/assets/key.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/resources/[housing]/brutal_keys/html/assets/panel_border.svg b/resources/[housing]/brutal_keys/html/assets/panel_border.svg new file mode 100644 index 000000000..b93f7497a --- /dev/null +++ b/resources/[housing]/brutal_keys/html/assets/panel_border.svg @@ -0,0 +1,3 @@ + +
+
diff --git a/resources/[housing]/brutal_keys/html/assets/people.png b/resources/[housing]/brutal_keys/html/assets/people.png new file mode 100644 index 000000000..eb9405158 Binary files /dev/null and b/resources/[housing]/brutal_keys/html/assets/people.png differ diff --git a/resources/[housing]/brutal_keys/html/assets/selected_key.svg b/resources/[housing]/brutal_keys/html/assets/selected_key.svg new file mode 100644 index 000000000..b0c77cc05 --- /dev/null +++ b/resources/[housing]/brutal_keys/html/assets/selected_key.svg @@ -0,0 +1,3 @@ + + + diff --git a/resources/[housing]/brutal_keys/html/assets/vehicle_key.svg b/resources/[housing]/brutal_keys/html/assets/vehicle_key.svg new file mode 100644 index 000000000..dee0095df --- /dev/null +++ b/resources/[housing]/brutal_keys/html/assets/vehicle_key.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/resources/[housing]/brutal_keys/html/desktop.ini b/resources/[housing]/brutal_keys/html/desktop.ini new file mode 100644 index 000000000..704fc3d2f Binary files /dev/null and b/resources/[housing]/brutal_keys/html/desktop.ini differ diff --git a/resources/[housing]/brutal_keys/html/index.html b/resources/[housing]/brutal_keys/html/index.html new file mode 100644 index 000000000..ba146598f --- /dev/null +++ b/resources/[housing]/brutal_keys/html/index.html @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + Brutal Keys + + + + +
+ +
+
+
+
+
+
+
+
+
+
+ +
+
+ +
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+ +
+ +
+
+
+
+
+
+
+ + +
+ +
+
+
+ +
+
+
+
+
+
+
+
+
+
+ + + + + + + + diff --git a/resources/[housing]/brutal_keys/html/script.js b/resources/[housing]/brutal_keys/html/script.js new file mode 100644 index 000000000..545c21980 --- /dev/null +++ b/resources/[housing]/brutal_keys/html/script.js @@ -0,0 +1,637 @@ +BGBlur = true +ActionsOpen = false +ChangedKeys = [] +DoorNotify = false +CurrentKeyPage = 1 + +let translations = {}; + +async function loadTranslations(lang) { + try { + const response = await fetch(`../locales/${lang}.json`); + translations = await response.json(); + updateText() + } catch (error) { + console.error("Error loading translation:", error); + } +} + +function updateText() { + document.querySelectorAll("[data-i18n]").forEach(element => { + const key = element.getAttribute("data-i18n"); + + if (element.hasAttribute("placeholder")) { + element.setAttribute("placeholder", translations[key]); + } else { + element.innerHTML = translations[key]; + } + }); +} + +function t(key) { + return translations[key] || key; +} + +window.addEventListener('message', function(event) { + let data = event.data + + if (data.action == "NUILanguage") { + loadTranslations(data.language); + } + else if (data.action === "OpenKeysMenu") { + MyKeys = data.mykeys + CreateKeyMenu() + BackgroundBlur("plugin_1", 'key_panel') + if (ActionsOpen){ + BackgroundBlur("plugin_1", 'key_panel', true) + MakeKeysDraggable() + } + else{ + BackgroundBlur("plugin_1", 'key_panel') + } + ChangedKeys = [] + } + if (data.action === "OpenLostKeyMenu") { + MyVehicles = data.myvehicles + VehicleKeyPrice = data.price + Currency = data.currencyform + CreateKeyPurchaseMenu() + show('key_purchase_menu') + BackgroundBlur("plugin_2", 'key_purchase_panel') + } + if (data.action === "DoorState") { + DoorState = data.status + if (DoorState == 'unlocked'){ + $(".key_notify .text").html(t('doors_unlocked')) + document.getElementById('line').classList.remove("red") + } + else{ + $(".key_notify .text").html(t('doors_locked')) + document.getElementById('line').classList.add("red") + } + $('.key_notify').css('display', 'block') + $('.key_notify .container').css('animation', 'container 1s ease both') + if (DoorNotify){ + clearTimeout(DoorNotify) + } + DoorNotify = setTimeout(() => { + $('.key_notify .container').css('animation', 'reverse_container 1s ease both') + setTimeout(() => { + $('.key_notify').css('display', 'none') + DoorNotify = false + }, 800); + }, 4000); + } + else if (data.action === "close") { + Close() + } +}) + +document.onkeydown = function(data) { + if (event.key == 'Escape') { + Close() + } +} + +function Close(){ + CloseKeyMenu() + hide('key_purchase_menu') + $.post('https://' + GetParentResourceName() + '/UseButton', JSON.stringify({action: "close", table:ChangedKeys})) + ChangedKeys = [] +} + +function CreateKeyPurchaseMenu(){ + $('.vehicles_container').html('') + for (let i = 0; i < MyVehicles.length; i++) { + $('.vehicles_container').append(` +
+
+
${MyVehicles[i].plate}
+
${VehicleKeyPrice.toLocaleString('hu-HU')+' '+Currency}
+ +
+ `) + } +} + +function SendBuyKeyForVehicle(plate){ + $.post('https://' + GetParentResourceName() + '/UseButton', JSON.stringify({action: "lostKey", plate})) +} + +function CreateKeyMenu(){ + $('.key_menu').css('display', 'block') + $('.key_menu .animation_element').css('animation', 'animation_element 1s ease both') + $('.key_menu .overflow_container').css('animation', 'overflow_container 1s ease both') + $('.key_menu .panel').css('animation', 'panel 1s ease both') + + CreatePageSelector() + InsertDataToPanel() +} + +function SendChangeLock(keyid){ + $.post('https://' + GetParentResourceName() + '/UseButton', JSON.stringify({action: "changeLock", keyid, table:ChangedKeys})) + ChangedKeys = [] +} + +function SendCopy(keyid){ + $.post('https://' + GetParentResourceName() + '/UseButton', JSON.stringify({action: "copyKey", keyid, table:ChangedKeys})) + ChangedKeys = [] +} + +function SendDeleteAll(keyid, plate){ + $.post('https://' + GetParentResourceName() + '/UseButton', JSON.stringify({action: "deleteAll", keyid, table:ChangedKeys, plate})) + ChangedKeys = [] +} + +function CloseKeyMenu(){ + $('.key_menu .animation_element').css('animation', 'reverse_animation_element 1s ease both') + $('.key_menu .overflow_container').css('animation', 'reverse_overflow_container 1s ease both') + $('.key_menu .panel').css('animation', 'reverse_panel 1s ease both') + + if (ActionsOpen){ + document.getElementById('actions_btn').classList.remove("active") + $('.key_menu .overflow_container').css('transform', 'translate(0px, -50%)') + + $('.actions_section #actions_panel').css('animation', 'reverse_actions_panel 0.3s both') + + MakeKeysNotDraggable() + + setTimeout(() => { + ActionsOpen = false + BackgroundBlur("plugin_1", 'key_panel') + $('.actions_section').css('display', 'none') + }, 400); + } + + setTimeout(() => { + $('.key_menu').css('display', 'none') + }, 700); +} + +function ChooseKeyPage(element, number){ + MakeKeysNotDraggable() + CurrentKeyPage = number+1 + for (let i = 0; i < NumberOfPages; i++) { + document.getElementById("page_"+i).classList.remove("choosed") + } + element.classList.add("choosed") + InsertDataToPanel() + if (ActionsOpen){ + MakeKeysDraggable() + } +} + +function CreatePageSelector(){ + BiggestSlot = 1 + for (let i = 0; i < MyKeys.length; i++) { + if (MyKeys[i].slot > BiggestSlot){ + BiggestSlot = MyKeys[i].slot + } + } + NumberOfPages = (BiggestSlot-(BiggestSlot%24))/24+1 + + $(".page_selector_container").html('') + if (NumberOfPages > 1){ + for (let i = 0; i < NumberOfPages; i++) { + if (CurrentKeyPage-1 == i){ + $(".page_selector_container").append(` +
+ `) + } + else{ + $(".page_selector_container").append(` +
+ `) + } + } + } +} + +function InsertDataToPanel(){ + $('.keys_container').html('') + for (let i = (CurrentKeyPage*24)-24; i < CurrentKeyPage*24; i++) { + if (MyKeys.length != 0){ + for (let _i = 0; _i < MyKeys.length; _i++) { + if (MyKeys[_i] != undefined && MyKeys[_i].slot-1 == i){ + let options = {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit"}; + let date = new Date(MyKeys[_i].time * 1000); + $('.keys_container').append(` +
+
+
${MyKeys[_i].quantity>1?MyKeys[_i].quantity:''}
+
${MyKeys[_i].label}
+ ${MyKeys[_i].type == 'temporary_key'?`
`:''} + +
+ `) + break + } + else if(_i+1 == MyKeys.length){ + $('.keys_container').append(` +
+
+
+ `) + break + } + } + } + else{ + $('.keys_container').append(` +
+
+
+ `) + } + } + document.querySelectorAll(".key_image").forEach(el => { + const dropdownMenu = new bootstrap.Dropdown(el); + el.addEventListener("contextmenu", function (event) { + event.preventDefault(); + document.querySelectorAll(".key_image").forEach(otherEl => { + if (otherEl !== el) { + new bootstrap.Dropdown(otherEl).hide(); + } + }); + dropdownMenu.show(); + }); + + document.addEventListener("click", function () { + dropdownMenu.hide(); + }); + }); +} + +function MakeKeysDraggable(){ + for (let i = (CurrentKeyPage*24)-24; i < CurrentKeyPage*24; i++) { + for (let _i = 0; _i < MyKeys.length; _i++) { + if (MyKeys[_i] != undefined && MyKeys[_i].slot-1 == i){ + dragElement(document.getElementById('key_'+i), 'key_'+i, MyKeys[_i].id, _i) + } + } + } +} + +function MakeKeysNotDraggable(){ + for (let i = (CurrentKeyPage*24)-24; i < CurrentKeyPage*24; i++) { + for (let _i = 0; _i < MyKeys.length; _i++) { + if (MyKeys[_i] != undefined && MyKeys[_i].slot-1 == i){ + document.getElementById('key_'+i).onmousedown = null + } + } + } +} + +function CreateActionPage(){ + if (!ActionsOpen){ + ActionsOpen = true + document.getElementById('actions_btn').classList.add("active") + $('.key_menu .overflow_container').css('transform', 'translate(-100px, -50%)') + BackgroundBlur("plugin_1", 'key_panel', true) + + $('#actions_panel').css('height', $('.key_menu .panel').height()+'px') + $('.actions_section #actions_panel').css('animation', 'actions_panel 0.3s ease both') + $('.actions_section').css('display', 'block') + + MakeKeysDraggable() + + TriggerCallback('getClosestPlayers', {}).done((cb) => { + ClosestPlayers = cb + $('.people_container').html('') + if (ClosestPlayers.length > 0){ + for (let i = 0; i < ClosestPlayers.length; i++) { + $('.people_container').append(` +
+
+
+
ID ${ClosestPlayers[i].id}
+
+ `) + } + } + else{ + $('.people_container').append(` +
+
+
x
+
+ `) + } + }); + } + else{ + document.getElementById('actions_btn').classList.remove("active") + $('.key_menu .overflow_container').css('transform', 'translate(0px, -50%)') + + $('.actions_section #actions_panel').css('animation', 'reverse_actions_panel 0.3s both') + + MakeKeysNotDraggable() + + setTimeout(() => { + ActionsOpen = false + BackgroundBlur("plugin_1", 'key_panel') + $('.actions_section').css('display', 'none') + }, 400); + } +} + +function TriggerCallback(event, data) { + data.action = event; + return $.post('https://' + GetParentResourceName() + '/UseButton', JSON.stringify(data)).promise(); +} + +function BackgroundBlur(element, target, value) { + if (BGBlur){ + var bodyRect = document.body.getBoundingClientRect(); + let elemRect = getTotalBoundingBox(target); + + if (!elemRect) return; + + let offset = []; + if (value){ + offset = [ + (elemRect.top - bodyRect.top)-2, + ((elemRect.right - bodyRect.right) * (-1))-150, + (elemRect.bottom - bodyRect.bottom)+2, + (elemRect.left - bodyRect.left)-100 + ]; + } + else{ + offset = [ + (elemRect.top - bodyRect.top)-2, + ((elemRect.right - bodyRect.right) * (-1))-1, + (elemRect.bottom - bodyRect.bottom)+2, + (elemRect.left - bodyRect.left)-1 + ]; + } + + $('#' + element).css('clip-path', `inset(${offset[0]}px ${offset[1]}px calc(100% - ${offset[2]}px) ${offset[3]}px)`); + } + else{ + $('#' + element).css('display', 'none') + } + +} + +function getTotalBoundingBox(target) { + const elem = document.getElementById(target); + if (!elem) return null; + + let elemRect = elem.getBoundingClientRect(); + let minX = elemRect.left; + let minY = elemRect.top; + let maxX = elemRect.right; + let maxY = elemRect.bottom; + + + Array.from(elem.children).forEach(child => { + let childRect = child.getBoundingClientRect(); + minX = Math.min(minX, childRect.left!=0?childRect.left:99999); + minY = Math.min(minY, childRect.top!=0?childRect.top:99999); + maxX = Math.max(maxX, childRect.right); + maxY = Math.max(maxY, childRect.bottom); + }); + + + return { + width: maxX - minX, + height: maxY - minY, + left: minX, + top: minY, + right: maxX, + bottom: maxY + }; +} + +function show(element) { + $("#" + element).css("display", "block") + document.getElementById(element).style.animation = "showmenu 0.35s ease"; +} + +function hide(element) { + document.getElementById(element).style.animation = "hidemenu 0.3s ease"; + setTimeout(function() { + $("#" + element).css("display", "none") + }, 300) +} + +function isNumber(evt) { + evt = (evt) ? evt : window.event + var charCode = (evt.which) ? evt.which : evt.keyCode + if (charCode > 31 && (charCode < 48 || charCode > 57)) { + return false + } + return true +} + +////////////////////////////////////////////// DRAGGING ////////////////////////////////////////////////// + +OGPos = {} + +function dragElement(elmnt, item, keyid, index) { + var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0; + + if (OGPos[item] == null){ + OGPos[item] = { x: null, y: null } + OGPos[item].x = elmnt.offsetLeft + OGPos[item].y = elmnt.offsetTop + } + + elmnt.onmousedown = dragMouseDown + + function dragMouseDown(e) { + e = e || window.event; + e.preventDefault(); + + pos3 = e.clientX; + pos4 = e.clientY; + document.onmouseup = closeDragElement; + document.onmousemove = elementDrag; + } + + function elementDrag(e) { + e = e || window.event + e.preventDefault() + + pos1 = pos3 - e.clientX + pos2 = pos4 - e.clientY + pos3 = e.clientX + pos4 = e.clientY + + elmnt.style.opacity = "0.8" + + elmnt.style.top = (elmnt.offsetTop - pos2) + "px" + elmnt.style.left = (elmnt.offsetLeft - pos1) + "px" + + if (elementsOverlap(elmnt, document.getElementById("key_panel"), true) == false && elementsOverlap(elmnt, document.getElementById("actions_panel")) == false){ + closeDragElement(e) + } + + for (let i = (CurrentKeyPage*24)-24; i < CurrentKeyPage*24; i++) { + if (document.getElementById("empty_"+i) != undefined){ + if (elementsOverlapPrecise(document.getElementById("empty_"+i), e.clientX, e.clientY) == false){ + document.getElementById('empty_'+i).classList.remove("hovered") + } + else{ + document.getElementById('empty_'+i).classList.add("hovered") + } + } + } + + for (let i = 0; i < ClosestPlayers.length; i++) { + if (elementsOverlapPrecise(document.getElementById("player_"+i), e.clientX, e.clientY) == false){ + document.getElementById('player_'+i).classList.remove("hovered") + } + else{ + document.getElementById('player_'+i).classList.add("hovered") + } + } + + if (elementsOverlapPrecise(document.getElementById("key_delete"), e.clientX, e.clientY) == false){ + document.getElementById('key_delete').classList.remove("hovered") + } + else{ + document.getElementById('key_delete').classList.add("hovered") + } + } + + function closeDragElement(e) { + UseElement(elmnt, item, e.clientX, e.clientY, keyid, index) + elmnt.style.opacity = "1" + document.onmouseup = null; + document.onmousemove = null; + } +} + +function UseElement(elmnt, item, X, Y, keyid, index){ + let elm = elmnt + + for (let i = (CurrentKeyPage*24)-24; i < CurrentKeyPage*24; i++) { + if (document.getElementById("empty_"+i) != undefined){ + if (elementsOverlapPrecise(document.getElementById("empty_"+i), X, Y) == false){ + document.getElementById('empty_'+i).classList.remove("hovered") + } + else{ + for (const key in ChangedKeys) { + if (ChangedKeys[key].keyid == keyid){ + ChangedKeys.splice(key, 1) + } + } + for (const key in MyKeys) { + if (MyKeys[key].id == keyid){ + if (MyKeys[key].oldSlot == undefined || MyKeys[key].oldSlot != i+1){ + ChangedKeys.push({keyid: keyid, slot:i+1, plate:MyKeys[key].plate}) + break + } + } + } + + MakeKeysNotDraggable() + if (MyKeys[index].oldSlot == undefined){ + MyKeys[index].oldSlot = MyKeys[index].slot + } + MyKeys[index].slot = i+1 + InsertDataToPanel() + MakeKeysDraggable() + return + } + } + } + + for (let i = 0; i < ClosestPlayers.length; i++) { + if (elementsOverlapPrecise(document.getElementById("player_"+i), X, Y)){ + $.post('https://' + GetParentResourceName() + '/UseButton', JSON.stringify({action: "giveKey", playerid:ClosestPlayers[i].id, keyid, table:ChangedKeys})) + document.getElementById('player_'+i).classList.remove("hovered") + ChangedKeys = [] + return + } + } + + if (elementsOverlapPrecise(document.getElementById("key_delete"), X, Y)){ + $.post('https://' + GetParentResourceName() + '/UseButton', JSON.stringify({action: "deleteKey", keyid, table:ChangedKeys, plate:MyKeys[index].plate})) + document.getElementById('key_delete').classList.remove("hovered") + ChangedKeys = [] + return + } + + /* if (elementsOverlap(elm, document.getElementById("head_box")) && Damages.head){ + ItemAnim(elm, item) + } + else if(elementsOverlap(elm, document.getElementById("head_box")) && Damages.head == false){ + WrongItemAnim(elm, item) + } + else{ + elm.style.top = OGPos[item].y + "px" + elm.style.left = OGPos[item].x + "px" + }*/ + + elm.style.top = OGPos[item].y + "px" + elm.style.left = OGPos[item].x + "px" +} + +function ItemAnim(elm, item, part){ + elm.style.animation = 'none'; + elm.offsetHeight; + elm.style.animation = "itemuseanim 1.2s"; + setTimeout(function(){ + elm.style.top = OGPos[item].y + "px" + elm.style.left = OGPos[item].x + "px" + elm.style.animation = 'none'; + Close() + },1200) + + $.post('https://'+GetParentResourceName()+'/UseButton', JSON.stringify({action:"MedicerMenu", type:"useitem", item, you:Mediceryou, part})) +} + +function WrongItemAnim(elm, item){ + elm.style.animation = 'none'; + elm.offsetHeight; + elm.style.animation = "itemnotuseanim 0.8s"; + setTimeout(function(){ + elm.style.top = OGPos[item].y + "px" + elm.style.left = OGPos[item].x + "px" + elm.style.animation = 'none'; + },800) +} + +function elementsOverlap(el1, el2, value) { + const domRect1 = el1.getBoundingClientRect(); + const domRect2 = el2.getBoundingClientRect(); + + if (value){ + return !( + domRect1.top+50 > domRect2.bottom || + domRect1.right-50 < domRect2.left || + domRect1.bottom-50 < domRect2.top || + domRect1.left-50 > domRect2.right + ); + } + else{ + return !( + domRect1.top+50 > domRect2.bottom || + domRect1.right-50 < domRect2.left || + domRect1.bottom-50 < domRect2.top || + domRect1.left+50 > domRect2.right + ); + } +} + +function elementsOverlapPrecise(el1, X, Y) { + const domRect1 = el1.getBoundingClientRect(); + + return !( + domRect1.top > Y || + domRect1.right < X || + domRect1.bottom < Y || + domRect1.left > X + ); + +} diff --git a/resources/[housing]/brutal_keys/html/style.css b/resources/[housing]/brutal_keys/html/style.css new file mode 100644 index 000000000..f57b2f4f8 --- /dev/null +++ b/resources/[housing]/brutal_keys/html/style.css @@ -0,0 +1,1032 @@ +@import url('https://fonts.cdnfonts.com/css/futura-pt'); + +body{ + font-family: 'Oswald', sans-serif; + user-select: none; + background: none; + font-display: fallback; +} + +:root{ + --main_color: rgb(251, 133, 16); + --background_color: rgb(34, 34, 39); + --text_color: white; +} + +button{ + outline: none; + border: none; + cursor: pointer; + transition: all 0.2s; +} + +button:disabled{ + opacity: 0.6; + cursor: none; +} + +button:hover{ + cursor: pointer; + filter: brightness(110%); +} + +button:disabled:hover{ + filter: none; +} + +button:active{ + transition: all 0.05s; + filter: brightness(70%); + scale: 0.9; +} + +button:disabled:active{ + filter: none; + scale: 1; +} + +::-webkit-scrollbar { + display: none; + width: 10px; +} + +::-webkit-scrollbar-track { + background: transparent; +} + +::-webkit-scrollbar-thumb { + background: #2129326b; + border-radius: 3vh; + border: solid 1px rgba(255, 255, 255, 0.432); +} + +hr{ + height: 2px; + background-color: white; +} + +.input-group input{ + background-color: rgba(255, 255, 255, 0.137); + color: white; + border: solid 2px rgba(211, 211, 211, 0.705); + outline: none; + text-align: center; + font-weight: 400; + font-size: 22px !important; + padding-top: 10px !important; +} + +.input-group input::placeholder{ + color: #ffffff8e; +} + +.input-group input:focus{ + color: white; + background-color: rgba(255, 255, 255, 0.267); + border: solid 2px rgba(211, 211, 211, 0.959); + outline: none; + box-shadow: none; +} + +.input-group input:disabled{ + background-color: rgba(52, 63, 73, 0.295); + color: #b1b1b1; + border: none; + outline: none; + text-align: center; +} + +.custom-checkbox .form-check-label{ + color: white; + font-size: 24px; + font-weight: 500; +} + +.custom-checkbox .form-check-input{ + height: 25px; + width: 25px; + background-color: rgba(255, 255, 255, 0.205); + border: solid 2px #D3D3D3; +} + +.custom-checkbox .form-check-input:checked{ + border: solid 3px #ffffff; + background-color: #79cfe0b2; + background-image: none; +} + +.range::-webkit-slider-thumb{ + -webkit-appearance: none; + appearance: none; + height: 15px; + width: 15px; + background: rgba(255, 255, 255, 0.7); + transform: rotate(45deg); + cursor: pointer; + box-shadow: none; + border: solid 2px white; + transition: 0.3s; +} + +.range::-webkit-slider-thumb:active{ + background: #32EBBE; +} + +.range{ + -webkit-appearance: none; + width: 80%; + height: 3px; + border-radius: 10px; + outline: none; + background-color: #B7B7B7; +} + +.custom-control.ios-switch { + scale: 1.6; + margin-bottom: 15px; +} + +.custom-control.ios-switch .ios-switch-control-input { + display: none; +} + +.custom-control.ios-switch .ios-switch-control-input:active~.ios-switch-control-indicator::after { + width: 20px; +} + +.custom-control.ios-switch .ios-switch-control-input:checked~.ios-switch-control-indicator { + border: 10px solid #79cfe0; + background: #79cfe0; +} + +.custom-control.ios-switch .ios-switch-control-input:checked~.ios-switch-control-indicator::after { + top: -8px; + left: 8px; +} + +.custom-control.ios-switch .ios-switch-control-input:checked:active~.ios-switch-control-indicator::after { + left: 4px; +} + +.custom-control.ios-switch .ios-switch-control-indicator { + display: inline-block; + position: relative; + margin: 0 10px; + top: 4px; + width: 36px; + height: 20px; + background: rgb(51, 49, 70); + border-radius: 16px; + transition: 0.3s; + border: 2px solid rgb(54, 72, 94); +} + +.custom-control.ios-switch .ios-switch-control-indicator::after { + content: ''; + display: block; + position: absolute; + width: 16px; + height: 16px; + border-radius: 16px; + transition: 0.3s; + top: 0px; + left: 0px; + background: rgb(236, 236, 236); +} + +.dropdown .dropdown-menu{ + position: absolute !important; + background-color: rgba(61, 61, 61, 0.705); + backdrop-filter: blur(20px); + border: none; + max-height: 200px; + overflow-y: auto; + border-radius: 0px; + padding: 10px; + z-index: 999999 !important; + padding-bottom: 20px; +} + +.dropdown .dropdown-menu .dropdown-item{ + color: white; + height: 40px; + transition: all 0.3s ease; + line-height: 30px; + font-size: 23px; + font-weight: 300; + border: solid 1px white; + text-align: center; + font-family: 'Futura PT', sans-serif; + text-shadow: 5px 1px 0px rgba(0, 0, 0, 0.479); +} + +.dropdown .dropdown-menu .dropdown-item:hover{ + background-color: rgba(192, 192, 192, 0.493); +} + +.dropdown .dropdown-menu .dropdown-item img{ + height: 35px; + width: 35px; + margin-top: -5px; + margin-left: -10px; + border-radius: 6px; +} + +.dropdown .dropdown-menu .time{ + position: absolute; + bottom: 0px; + right: 10px; + font-size: 15px; + font-family: 'Futura PT', sans-serif; + color: white; + font-weight: 300; +} + +/* //////////////////////////////////////////////////////// MAIN THINGS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + +.key_menu{ + display: none; +} + +.key_menu .animation_element{ + position: absolute; + top: 150%; + left: -50%; + height: 150%; + width: 140%; + transform: translate(-50%, -50%) rotate(-45deg); + background-color: white; + animation: animation_element 1.5s ease both; + z-index: 10000; +} + +@keyframes animation_element { + 99%{ + opacity: 1; + } + 100%{ + transform: translate(150%, -200%) rotate(-45deg); + opacity: 0; + } +} + +@keyframes reverse_animation_element { + 0%{ + transform: translate(150%, -200%) rotate(-45deg); + } + 99%{ + opacity: 1; + } + 100%{ + opacity: 0; + } +} + +.key_menu .overflow_container{ + position: absolute; + top: 50%; + right: 40px; + transform: translate(0%, -50%); + height: 690px; + width: 420px; + overflow: hidden; + transition: all 0.3s ease; + z-index: 100; + animation: overflow_container 2.5s both; +} + +@keyframes overflow_container { + 99%{ + overflow: hidden; + } + 100%{ + overflow: visible; + } +} + +@keyframes reverse_overflow_container { + 99%{ + overflow: hidden; + } + 100%{ + overflow: hidden; + } +} + +.key_menu .panel{ + position: absolute; + top: 50%; + left: 50%; + height: 670px; + width: 400px; + transform: translate(-50%, -50%); + background-color: rgba(61, 61, 61, 0.425); + backdrop-filter: blur(25px); + font-family: 'Futura PT', sans-serif; + animation: panel 1.5s ease both; +} + +@keyframes panel { + 0%{ + opacity: 0; + } + 20%{ + opacity: 0; + } + 40%{ + opacity: 1; + } +} + +@keyframes reverse_panel { + 0%{ + opacity: 1; + } + 22%{ + opacity: 1; + } + 50%{ + opacity: 0; + } + 100%{ + opacity: 0; + } +} + +.panel .panel_border_top{ + position: absolute; + top: -10px; + left: -10px; + height: 25px; + width: 25px; + background-image: url('assets/panel_border.svg'); + background-repeat: no-repeat; + background-position: center; +} + +.panel .panel_border_bottom{ + position: absolute; + bottom: -10px; + right: -10px; + transform: rotate(180deg); + height: 25px; + width: 25px; + background-image: url('assets/panel_border.svg'); + background-repeat: no-repeat; + background-position: center; +} + +.panel .top_line{ + position: absolute; + top: 16px; + left: 14px; + height: 1px; + width: 230px; + background-color: rgba(255, 255, 255, 0.37); + animation: top_line 4s ease; +} + +@keyframes top_line { + 0%{ + transform: scaleX(70%) translateX(-20%); + } + 100%{ + transform: scaleX(100%); + } +} + +.panel .top_box{ + position: absolute; + top: 14px; + left: 14px; + height: 4px; + width: 4px; + background-color: rgba(255, 255, 255, 0.616); +} + +.panel .title{ + position: absolute; + top: 20px; + left: 20px; + font-weight: 400; + font-size: 43px; + line-height: 48px; + color: #FFFFFF; + text-shadow: 6px 1px 0px rgba(0, 0, 0, 0.30); +} + +.panel .action_btn{ + position: relative; + float: right; + height: 45px; + padding-inline: 15px; + font-weight: 300; + font-size: 22px; + line-height: 24px; + color: #FFFFFF; + text-shadow: 5px 1px 0px rgba(0, 0, 0, 0.40); + background-color: transparent; + filter: brightness(100%); + opacity: 1; + overflow: hidden; +} + +.panel .action_btn:hover::before, .key_menu .panel .action_btn:hover::after{ + filter: brightness(100%); +} + +.action_btn::before, .action_btn::after{ + content: ""; + position: absolute; + height: 15px; + width: 15px; + background-image: url('assets/panel_border.svg'); + background-size: cover; + background-repeat: no-repeat; + background-position: center; + filter: brightness(70%); + transition: all 0.3s ease; +} + +.panel .action_btn::before{ + top: 0px; + left: 0px; +} + +.panel .action_btn::after{ + bottom: 0px; + right: 0px; + transform: rotate(180deg); +} + +.panel .action_btn .bg{ + position: absolute; + top: 0; + left: 0; + height: 100%; + width: 100%; + background-color: #21cc9a; + box-shadow: 0px 0px 10px 0px #21cc99a8; + z-index: -10; + transform: scaleX(0.01) rotate(-55deg); + transition: all 0.6s ease; + opacity: 0; +} + +.panel .action_btn.active .bg{ + transform: scaleX(2) rotate(-55deg); + opacity: 1; +} + +.panel .action_btn .line{ + position: absolute; + bottom: 7px; + left: 10px; + height: 1px; + width: 60%; + background-color: white; + transition: all 0.6s ease; +} + +.panel .action_btn:hover .line{ + transform: scaleX(1.17) translateX(5px); +} + +.panel .page_selector_container{ + position: absolute; + top: 70px; + left: 20px; +} + +.panel .page_selector_container .page_element{ + display: inline-block; + width: 0px; + height: 0px; + border-style: solid; + border-width: 20px 25px 0 0; + border-color: #32ebbd4d #32ebbd transparent transparent; + margin-inline: 3px; + transition: all 0.3s ease; + background-color: transparent; + cursor: pointer; + outline: rgba(255, 255, 255, 0.747); +} + +.panel .page_selector_container .page_element.choosed{ + border-color: #32EBBE #32EBBE transparent transparent; + outline: solid 2px rgba(255, 255, 255, 0.747); + border-width: 20px 40px 0 0; +} + +.page_element:hover{ + filter: brightness(110%); +} + +.page_element:active{ + transition: all 0.05s; + filter: brightness(70%); + scale: 0.9; +} + +.key_menu .panel .keys_container{ + position: relative; + margin-top: 85px; + height: 580px; + width: 100%; + display: flex; + flex-wrap: wrap; + padding-inline: 10px; + margin-bottom: 20px; + padding-bottom: 8px; +} + +.key_menu .panel .keys_container .key_element{ + position: relative; + height: 78px; + width: 78px; + margin-top: 16px; + margin-inline: 8px; + transition: background-color 0.3s ease; + cursor: pointer; +} + +.key_menu .panel .keys_container .key_element.hovered{ + background-color: rgba(121, 215, 190, 0.349); + border: solid 1px rgba(255, 255, 255, 0.247); +} + +.key_menu .panel .keys_container .key_element .key_border{ + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + height: 80px; + width: 80px; + background-image: url('assets/basic_key.svg'); + background-repeat: no-repeat; + background-position: center; +} + +.key_menu .panel .keys_container .key_element.hovered .key_border{ + background-image: url('assets/selected_key.svg'); + filter: brightness(0) saturate(100%) invert(73%) sepia(96%) saturate(177%) hue-rotate(109deg) brightness(92%) contrast(86%); +} + +.key_menu .panel .keys_container .key_element .number{ + position: absolute; + top: 3px; + right: 5px; + font-style: normal; + font-weight: 400; + font-size: 20px; + line-height: 20px; + text-align: center; + color: rgba(255, 255, 255, 0.65); + text-shadow: 4px 1px 0px rgba(0, 0, 0, 0.24); +} + +.key_menu .panel .keys_container .key_element.hovered .number{ + color: white; +} + +.key_menu .panel .keys_container .key_element .temporary{ + position: absolute; + top: 5px; + left: 5px; + width: 0; + height: 0; + border-style: solid; + border-width: 10px 10px 0 0; + border-color: #32EBBE #32ebbd3d transparent transparent; + animation: temporary 4s ease-in-out infinite; +} + +@keyframes temporary { + 50%{ + border-color: #32ebbd3d #32EBBE transparent transparent; + } +} + +.key_menu .panel .keys_container .key_element .name{ + position: absolute; + bottom: 5px; + width: 100%; + font-style: normal; + font-weight: 400; + font-size: 14px; + line-height: 14px; + text-align: center; + color: rgba(255, 255, 255, 0.65); + text-shadow: 4px 1px 0px rgba(0, 0, 0, 0.24); +} + +.key_menu .panel .keys_container .key_element .key_image{ + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + height: 80%; + width: 80%; + background-image: url('assets/key.svg'); + background-repeat: no-repeat; + background-position: center; +} + +.key_menu .panel .keys_container .key_element .key_image.vehicle{ + background-image: url('assets/vehicle_key.svg'); +} + +.key_menu .panel .keys_container .key_element .dropdown{ + position: absolute; + height: 100%; + width: 100%; +} + +.key_menu .panel .keys_container .key_element .dropdown .dropdown_btn{ + position: absolute; + height: 100%; + width: 100%; + background-color: transparent; +} + +.actions_section{ + display: none; +} + +.key_menu .actions_section #actions_panel{ + position: absolute; + top: 50%; + right: 20px; + transform: translate(0%, -50%); + width: 110px; + background-color: rgba(61, 61, 61, 0.425); + backdrop-filter: blur(25px); + font-family: 'Futura PT', sans-serif; + z-index: 10; + overflow-y: auto; + border-top: solid white 3px; + transition: all 0.3s ease; +} + +@keyframes actions_panel { + 0%{ + transform: translate(0px, -50%) scale(1, 0.0); + } + 100%{ + transform: translate(0px, -50%); + } +} + +@keyframes reverse_actions_panel { + 0%{ + transform: translate(0px, -50%); + } + 100%{ + transform: translate(0px, -50%) scale(1, 0.0); + } +} + +.key_menu .actions_section #actions_panel .key_deleting{ + position: relative; + margin: 16px; + height: 80px; + width: 80px; + background-image: url('assets/selected_key.svg'); + background-repeat: no-repeat; + background-position: center; + filter: brightness(0) saturate(100%) invert(49%) sepia(41%) saturate(4609%) hue-rotate(329deg) brightness(99%) contrast(97%); + transition: all 0.3s ease; +} + +.key_menu .actions_section #actions_panel .key_deleting.hovered{ + background-color: #f9545485; +} + +.key_menu .actions_section #actions_panel .key_deleting .bg{ + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + height: 78px; + width: 78px; + background-image: repeating-linear-gradient(45deg, #f95454 0, #f95454 11px, transparent 0, transparent 50%); + background-size: 30px 30px; + background-color: rgba(0, 0, 0, 0.342); + opacity: 0.3; +} + +.key_menu .actions_section #actions_panel .key_deleting .bin{ + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + height: 40%; + width: 40%; + background-image: url('assets/bin.png'); + background-repeat: no-repeat; + background-position: center; + background-size: contain; +} + +.key_menu .actions_section #actions_panel hr{ + border: none; + height: 2px; + background-color: rgba(255, 255, 255, 0.671); + opacity: 1; + width: 70%; + margin-left: 15%; +} + +.key_menu .actions_section #actions_panel .people_container{ + position: relative; + width: 100%; +} + +.key_menu .actions_section #actions_panel .people_container .people_element{ + position: relative; + height: 78px; + width: 78px; + margin-bottom: 16px; + margin-inline: 16px; + transition: all 0.3s ease; + cursor: pointer; +} + +.key_menu .actions_section #actions_panel .people_container .people_element.hovered{ + background-color: rgba(255, 255, 255, 0.253); +} + +.key_menu .actions_section #actions_panel .people_container .people_element .element_border{ + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + height: 80px; + width: 80px; + background-image: url('assets/basic_key.svg'); + background-repeat: no-repeat; + background-position: center; +} + +.key_menu .actions_section #actions_panel .people_container .people_element.hovered .element_border{ + background-image: url('assets/selected_key.svg'); +} + +.key_menu .actions_section #actions_panel .people_container .people_element .people_image{ + position: absolute; + top: 40%; + left: 50%; + transform: translate(-50%, -50%); + height: 70%; + width: 70%; + background-image: url('assets/people.png'); + background-size: contain; + background-repeat: no-repeat; + background-position: center; +} + +.key_menu .actions_section #actions_panel .people_container .people_element .id{ + position: absolute; + bottom: 0px; + width: 100%; + font-style: normal; + font-weight: 400; + font-size: 18px; + line-height: 24px; + text-align: center; + color: rgb(255, 255, 255); + text-shadow: 4px 1px 0px rgba(0, 0, 0, 0.24); +} + +.key_menu .actions_section #actions_panel .people_container .people_element .text{ + position: absolute; + top: 45%; + transform: translate(0%, -50%); + width: 100%; + font-style: normal; + font-weight: 400; + font-size: 65px; + text-align: center; + color: rgba(255, 255, 255, 0.404); +} + +.key_purchase_menu{ + display: none; +} + +.key_purchase_menu .panel{ + position: absolute; + top: 50%; + left: 50%; + width: 400px; + transform: translate(-50%, -50%); + background-color: rgba(61, 61, 61, 0.425); + backdrop-filter: blur(25px); + font-family: 'Futura PT', sans-serif; + animation: panel 1.5s ease both; +} + +.key_purchase_menu .panel .description{ + position: absolute; + top: 65px; + left: 20px; + font-weight: 200; + font-size: 15px; + line-height: 17px; + color: #ffffffb6; + width: 300px; +} + +.key_purchase_menu .panel .vehicles_container{ + position: relative; + margin-top: 40px; + max-height: 570px; + width: 100%; + display: flex; + flex-wrap: wrap; + padding-inline: 8px; + margin-bottom: 10px; + padding-bottom: 16px; + overflow-y: auto; +} + +.key_purchase_menu .panel .vehicles_container .vehicle_element{ + position: relative; + height: 60px; + width: 380px; + margin-top: 16px; + margin-inline: 8px; + background-color: rgba(255, 255, 255, 0.171); + backdrop-filter: blur(60px); +} + +.key_purchase_menu .panel .vehicles_container .vehicle_element .plate{ + position: absolute; + top: 50%; + left: 20px; + transform: translate(0%, -50%); + color: white; + font-size: 23px; + text-shadow: 5px 1px 0px rgba(0, 0, 0, 0.397); + font-weight: 300; +} + +.key_purchase_menu .panel .vehicles_container .vehicle_element .price{ + position: absolute; + top: 50%; + right: 120px; + transform: translate(0%, -50%); + color: #79D7BE; + font-size: 23px; + font-weight: 500; +} + +.key_purchase_menu .panel .vehicles_container .vehicle_element .action_btn{ + position: absolute; + top: 50%; + right: 15px; + transform: translate(0%, -50%); +} + +.key_purchase_menu .panel .vehicles_container .vehicle_element .element_border{ + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + height: 60px; + width: 370px; + background-image: url('assets/basic_vehicle.svg'); + background-repeat: no-repeat; + background-position: center; + background-size: contain; +} + +@keyframes showmenu { + 0%{ + opacity: 0; + } +} + +@keyframes hidemenu { + 100%{ + opacity: 0; + } +} + +.key_notify{ + position: absolute; + bottom: 50px; + right: 200px; + height: 60px; + width: 220px; + font-family: 'Futura PT', sans-serif; + display: none; +} + +.key_notify .container{ + position: absolute; + top: 50%; + left: 50%; + height: 100%; + width: 100%; + transform: translate(-50%, -50%); + background-color: #3d3d3dd8; + animation: container 1s ease both; + overflow: hidden; +} + +@keyframes container { + 0%{ + width: 0%; + transform: translate(-50%, -50%) scaleX(0); + } + 40%{ + transform: translate(-50%, -50%) scaleX(1); + } + 100%{ + width: 100%; + } +} + +@keyframes reverse_container { + 0%{ + width: 100%; + } + 60%{ + transform: translate(-50%, -50%) scaleX(1); + } + 100%{ + width: 0%; + transform: translate(-50%, -50%) scaleX(0); + } +} + + +.key_notify .container::before, .key_notify .container::after{ + content: ""; + position: absolute; + height: 20px; + width: 20px; + background-image: url('assets/panel_border.svg'); + background-size: cover; + background-repeat: no-repeat; + background-position: center; +} + +.key_notify .container::before{ + top: 0px; + left: 0px; +} + +.key_notify .container::after{ + bottom: 0px; + right: 0px; + transform: rotate(180deg); +} + +.key_notify .text{ + position: absolute; + top: 35%; + left: 50%; + transform: translate(-50%, -50%); + text-align: center; + color: white; + font-size: 20px; + text-shadow: 5px 1px 0px rgba(0, 0, 0, 0.397); + white-space: nowrap; +} + +.key_notify .line{ + position: absolute; + bottom: 10px; + left: 50%; + transform: translate(-50%, 0%); + height: 10px; + width: 200px; + background-image: url('assets/door_line.svg'); + background-size: cover; + background-repeat: no-repeat; + background-position: center; +} + +.key_notify .line.red{ + filter: brightness(0) saturate(100%) invert(52%) sepia(82%) saturate(3630%) hue-rotate(329deg) brightness(100%) contrast(97%); +} + +.key_notify .line .prog_line{ + position: absolute; + left: 7%; + width: 93%; + height: 100%; + background-color: #79D7BE; + animation: prog_line 2s ease both; +} + +@keyframes prog_line { + 0%{ + width: 0; + } + 100%{ + width: 93%; + } +} \ No newline at end of file diff --git a/resources/[housing]/brutal_keys/locales/ar.json b/resources/[housing]/brutal_keys/locales/ar.json new file mode 100644 index 000000000..3e6da1d11 --- /dev/null +++ b/resources/[housing]/brutal_keys/locales/ar.json @@ -0,0 +1,13 @@ +{ + "keys": "مفتاح", + "actions": "الإجراءات
", + "back": "رجوع
", + "buy_keys": "شراء مفتاح", + "buy_keys_des": "هنا يمكنك شراء مفتاح جديد إذا فقدت جميع المفاتيح.", + "doors_unlocked": "الباب مفتوح", + "doors_locked": "الباب مغلق", + "buy": "شراء", + "copy": "نسخ", + "change_lock": "تغيير القفل", + "delete_all": "حذف الكل" +} diff --git a/resources/[housing]/brutal_keys/locales/cs.json b/resources/[housing]/brutal_keys/locales/cs.json new file mode 100644 index 000000000..5f4e28f3c --- /dev/null +++ b/resources/[housing]/brutal_keys/locales/cs.json @@ -0,0 +1,13 @@ +{ + "keys": "KLÍČ", + "actions": "AKCE
", + "back": "ZPĚT
", + "buy_keys": "KOUPIT KLÍČ", + "buy_keys_des": "Zde si můžeš koupit nový klíč, pokud jsi všechny ztratil.", + "doors_unlocked": "DVEŘE OTEVŘENÉ", + "doors_locked": "DVEŘE ZAVŘENÉ", + "buy": "KOUPIT", + "copy": "KOPÍROVAT", + "change_lock": "ZMĚNIT ZÁMEK", + "delete_all": "SMAZAT VŠE" +} diff --git a/resources/[housing]/brutal_keys/locales/de.json b/resources/[housing]/brutal_keys/locales/de.json new file mode 100644 index 000000000..5a8448e71 --- /dev/null +++ b/resources/[housing]/brutal_keys/locales/de.json @@ -0,0 +1,13 @@ +{ + "keys": "SCHLUSS", + "actions": "AKTIONEN
", + "back": "ZURUCK
", + "buy_keys": "KAUF SCHLUSS", + "buy_keys_des": "Hier kannst du einen neuen Schluss kaufen, wenn alle verloren sind.", + "doors_unlocked": "TUR OFFEN", + "doors_locked": "TUR ZU", + "buy": "KAUFEN", + "copy": "KOPIEREN", + "change_lock": "SCHLOSS WECHSEL", + "delete_all": "ALLES LOSCHEN" +} diff --git a/resources/[housing]/brutal_keys/locales/desktop.ini b/resources/[housing]/brutal_keys/locales/desktop.ini new file mode 100644 index 000000000..704fc3d2f Binary files /dev/null and b/resources/[housing]/brutal_keys/locales/desktop.ini differ diff --git a/resources/[housing]/brutal_keys/locales/en.json b/resources/[housing]/brutal_keys/locales/en.json new file mode 100644 index 000000000..836704e6f --- /dev/null +++ b/resources/[housing]/brutal_keys/locales/en.json @@ -0,0 +1,13 @@ +{ + "keys": "KEYS", + "actions": "ACTIONS
", + "back": "BACK
", + "buy_keys": "BUY KEYS", + "buy_keys_des": "Here you can buy keys for your vehicles if you have managed to lose all of them.", + "doors_unlocked": "DOORS UNLOCKED", + "doors_locked": "DOORS LOCKED", + "buy": "BUY", + "copy": "COPY", + "change_lock": "CHANGE LOCK", + "delete_all": "DELETE ALL" +} diff --git a/resources/[housing]/brutal_keys/locales/fr.json b/resources/[housing]/brutal_keys/locales/fr.json new file mode 100644 index 000000000..cad03c324 --- /dev/null +++ b/resources/[housing]/brutal_keys/locales/fr.json @@ -0,0 +1,13 @@ +{ + "keys": "CLE", + "actions": "ACTIONS
", + "back": "RETOUR
", + "buy_keys": "ACHAT CLE", + "buy_keys_des": "Ici, tu peux acheter une nouvelle cle si toutes sont perdues.", + "doors_unlocked": "PORTE OUVERTE", + "doors_locked": "PORTE FERME", + "buy": "ACHETER", + "copy": "COPIER", + "change_lock": "CHANGER SERRURE", + "delete_all": "SUPPRIMER TOUT" +} diff --git a/resources/[housing]/brutal_keys/locales/hu.json b/resources/[housing]/brutal_keys/locales/hu.json new file mode 100644 index 000000000..8871af6c8 --- /dev/null +++ b/resources/[housing]/brutal_keys/locales/hu.json @@ -0,0 +1,13 @@ +{ + "keys": "KULCS", + "actions": "MŰVELETEK
", + "back": "VISSZA
", + "buy_keys": "VÁSÁRLÁS", + "buy_keys_des": "Itt vásárolhatsz kulcsokat a járműveidhez, ha az összeset elvesztetted.", + "doors_unlocked": "AJTÓK NYITVA", + "doors_locked": "AJTÓK ZÁRVA", + "buy": "VÁSÁRLÁS", + "copy": "MÁSOLÁS", + "change_lock": "ZÁRCSERE", + "delete_all": "ÖSSZES TÖRLÉSE" +} diff --git a/resources/[housing]/brutal_keys/locales/it.json b/resources/[housing]/brutal_keys/locales/it.json new file mode 100644 index 000000000..3273cdb10 --- /dev/null +++ b/resources/[housing]/brutal_keys/locales/it.json @@ -0,0 +1,13 @@ +{ + "keys": "CHIAVE", + "actions": "AZIONI
", + "back": "INDIETRO
", + "buy_keys": "COMPRA CHIAVE", + "buy_keys_des": "Qui puoi comprare una nuova chiave se le hai perse tutte.", + "doors_unlocked": "PORTA APERTA", + "doors_locked": "PORTA CHIUSA", + "buy": "COMPRA", + "copy": "COPIA", + "change_lock": "CAMBIA SERRATURA", + "delete_all": "ELIMINA TUTTO" +} diff --git a/resources/[housing]/brutal_keys/locales/nl.json b/resources/[housing]/brutal_keys/locales/nl.json new file mode 100644 index 000000000..8de839bcc --- /dev/null +++ b/resources/[housing]/brutal_keys/locales/nl.json @@ -0,0 +1,13 @@ +{ + "keys": "SLEUTEL", + "actions": "ACTIES
", + "back": "TERUG
", + "buy_keys": "KOOP SLEUTEL", + "buy_keys_des": "Hier kun je een nieuwe sleutel kopen als je alles kwijt bent.", + "doors_unlocked": "DEUR OPEN", + "doors_locked": "DEUR DICHT", + "buy": "KOPEN", + "copy": "KOPIEREN", + "change_lock": "VERVANG SLOT", + "delete_all": "VERWIJDER ALLES" +} diff --git a/resources/[housing]/brutal_keys/locales/pl.json b/resources/[housing]/brutal_keys/locales/pl.json new file mode 100644 index 000000000..cabbde79c --- /dev/null +++ b/resources/[housing]/brutal_keys/locales/pl.json @@ -0,0 +1,13 @@ +{ + "keys": "KLUCZ", + "actions": "AKCJE
", + "back": "WSTECZ
", + "buy_keys": "KUP KLUCZ", + "buy_keys_des": "Tutaj mozesz kupic nowy klucz, jesli zgubiles wszystkie.", + "doors_unlocked": "DRZWI OTWARTE", + "doors_locked": "DRZWI ZAMKNIETE", + "buy": "KUP", + "copy": "KOPIUJ", + "change_lock": "ZMIEN ZAMEK", + "delete_all": "USUN WSZYSTKO" +} diff --git a/resources/[housing]/brutal_keys/locales/pt.json b/resources/[housing]/brutal_keys/locales/pt.json new file mode 100644 index 000000000..25aead284 --- /dev/null +++ b/resources/[housing]/brutal_keys/locales/pt.json @@ -0,0 +1,13 @@ +{ + "keys": "CHAVE", + "actions": "ACOES
", + "back": "VOLTAR
", + "buy_keys": "COMPRAR CHAVE", + "buy_keys_des": "Aqui voce pode comprar uma nova chave se perdeu todas.", + "doors_unlocked": "PORTA ABERTA", + "doors_locked": "PORTA FECHADA", + "buy": "COMPRAR", + "copy": "COPIAR", + "change_lock": "TROCAR FECHADURA", + "delete_all": "APAGAR TUDO" +} diff --git a/resources/[housing]/brutal_keys/locales/ro.json b/resources/[housing]/brutal_keys/locales/ro.json new file mode 100644 index 000000000..30b149657 --- /dev/null +++ b/resources/[housing]/brutal_keys/locales/ro.json @@ -0,0 +1,13 @@ +{ + "keys": "CHEIE", + "actions": "ACȚIUNI
", + "back": "ÎNAPOI
", + "buy_keys": "CUMPĂRĂ CHEIE", + "buy_keys_des": "Aici poți cumpăra o nouă cheie dacă le-ai pierdut pe toate.", + "doors_unlocked": "UȘA DESCHISĂ", + "doors_locked": "UȘA ÎNCHISĂ", + "buy": "CUMPĂRĂ", + "copy": "COPIAZĂ", + "change_lock": "SCHIMBĂ LACĂTUL", + "delete_all": "ȘTERGE TOT" +} diff --git a/resources/[housing]/brutal_keys/locales/ru.json b/resources/[housing]/brutal_keys/locales/ru.json new file mode 100644 index 000000000..8f123132c --- /dev/null +++ b/resources/[housing]/brutal_keys/locales/ru.json @@ -0,0 +1,13 @@ +{ + "keys": "КЛЮЧ", + "actions": "ДЕЙСТВИЯ
", + "back": "НАЗАД
", + "buy_keys": "КУПИТЬ КЛЮЧ", + "buy_keys_des": "Здесь можно купить новый ключ, если все потеряны.", + "doors_unlocked": "ДВЕРЬ ОТКРЫТА", + "doors_locked": "ДВЕРЬ ЗАКРЫТА", + "buy": "КУПИТЬ", + "copy": "КОПИРОВАТЬ", + "change_lock": "СМЕНИТЬ ЗАМОК", + "delete_all": "УДАЛИТЬ ВСЕ" +} diff --git a/resources/[housing]/brutal_keys/locales/sp.json b/resources/[housing]/brutal_keys/locales/sp.json new file mode 100644 index 000000000..e73d566ac --- /dev/null +++ b/resources/[housing]/brutal_keys/locales/sp.json @@ -0,0 +1,13 @@ +{ + "keys": "LLAVE", + "actions": "ACCIONES
", + "back": "ATRAS
", + "buy_keys": "COMPRAR LLAVE", + "buy_keys_des": "Aqui puedes comprar una nueva llave si perdiste todas.", + "doors_unlocked": "PUERTA ABIERTA", + "doors_locked": "PUERTA CERRADA", + "buy": "COMPRAR", + "copy": "COPIAR", + "change_lock": "CAMBIO CERRADURA", + "delete_all": "BORRAR TODO" +} diff --git a/resources/[housing]/brutal_keys/locales/sv.json b/resources/[housing]/brutal_keys/locales/sv.json new file mode 100644 index 000000000..d5e80a192 --- /dev/null +++ b/resources/[housing]/brutal_keys/locales/sv.json @@ -0,0 +1,13 @@ +{ + "keys": "NYCKEL", + "actions": "ÅTGÄRDER
", + "back": "TILLBAKA
", + "buy_keys": "KÖP NYCKEL", + "buy_keys_des": "Här kan du köpa en ny nyckel om du har tappat alla.", + "doors_unlocked": "DÖRR ÖPPEN", + "doors_locked": "DÖRR LÅST", + "buy": "KÖP", + "copy": "KOPIERA", + "change_lock": "BYT LÅS", + "delete_all": "RADERA ALLT" +} diff --git a/resources/[housing]/brutal_keys/locales/tr.json b/resources/[housing]/brutal_keys/locales/tr.json new file mode 100644 index 000000000..b59364444 --- /dev/null +++ b/resources/[housing]/brutal_keys/locales/tr.json @@ -0,0 +1,13 @@ +{ + "keys": "ANAHTAR", + "actions": "EYLEMLER
", + "back": "GERI
", + "buy_keys": "ANAHTAR AL", + "buy_keys_des": "Buradan tum anahtarlarini kaybettiysen yeni bir tane alabilirsin.", + "doors_unlocked": "KAPI ACIK", + "doors_locked": "KAPI KAPALI", + "buy": "AL", + "copy": "KOPYALA", + "change_lock": "KILIT DEGISTIR", + "delete_all": "HEPSINI SIL" +} diff --git a/resources/[housing]/brutal_keys/server/desktop.ini b/resources/[housing]/brutal_keys/server/desktop.ini new file mode 100644 index 000000000..704fc3d2f Binary files /dev/null and b/resources/[housing]/brutal_keys/server/desktop.ini differ diff --git a/resources/[housing]/brutal_keys/server/server.lua b/resources/[housing]/brutal_keys/server/server.lua new file mode 100644 index 000000000..16a27222f Binary files /dev/null and b/resources/[housing]/brutal_keys/server/server.lua differ diff --git a/resources/[housing]/brutal_keys/sv_utils.lua b/resources/[housing]/brutal_keys/sv_utils.lua new file mode 100644 index 000000000..f69a65847 --- /dev/null +++ b/resources/[housing]/brutal_keys/sv_utils.lua @@ -0,0 +1,25 @@ +function StaffCheck(source) + local staff = false + + if Config.Core:upper() == 'ESX'then + local player = Core.GetPlayerFromId(source) + local playerGroup = player.getGroup() + + for i, Group in ipairs(Config.AdminGroups) do + if playerGroup == Group then + staff = true + break + end + end + elseif Config.Core:upper() == 'QBCORE' then + + for i, Group in ipairs(Config.AdminGroups) do + if Core.Functions.HasPermission(source, Group) or IsPlayerAceAllowed(source, Group) or IsPlayerAceAllowed(source, 'command') then + staff = true + break + end + end + end + + return staff +end \ No newline at end of file