From ae32fd0e86c690f393db01da4fba7911fa8dbb68 Mon Sep 17 00:00:00 2001 From: Andyyy7666 <86536434+Andyyy7666@users.noreply.github.com> Date: Thu, 23 Dec 2021 22:40:54 +0100 Subject: [PATCH] Add files via upload --- ND_Core/config.lua | 114 ++++++ ND_Core/fxmanifest.lua | 43 +++ ND_Core/query.sql | 15 + ND_Core/source/client/commands.lua | 109 ++++++ ND_Core/source/client/main.lua | 454 +++++++++++++++++++++++ ND_Core/source/server/commands.lua | 52 +++ ND_Core/source/server/discord.lua | 100 +++++ ND_Core/source/server/main.lua | 154 ++++++++ ND_Core/source/ui/Logo.png | Bin 0 -> 23945 bytes ND_Core/source/ui/index.html | 180 +++++++++ ND_Core/source/ui/js/jquery-3.6.0.min.js | 2 + ND_Core/source/ui/js/listener.js | 274 ++++++++++++++ ND_Core/source/ui/style.css | 281 ++++++++++++++ 13 files changed, 1778 insertions(+) create mode 100644 ND_Core/config.lua create mode 100644 ND_Core/fxmanifest.lua create mode 100644 ND_Core/query.sql create mode 100644 ND_Core/source/client/commands.lua create mode 100644 ND_Core/source/client/main.lua create mode 100644 ND_Core/source/server/commands.lua create mode 100644 ND_Core/source/server/discord.lua create mode 100644 ND_Core/source/server/main.lua create mode 100644 ND_Core/source/ui/Logo.png create mode 100644 ND_Core/source/ui/index.html create mode 100644 ND_Core/source/ui/js/jquery-3.6.0.min.js create mode 100644 ND_Core/source/ui/js/listener.js create mode 100644 ND_Core/source/ui/style.css diff --git a/ND_Core/config.lua b/ND_Core/config.lua new file mode 100644 index 0000000..e9f88d7 --- /dev/null +++ b/ND_Core/config.lua @@ -0,0 +1,114 @@ +------------------------------------------------------------------------ +------------------------------------------------------------------------ +-- -- +-- For support join my discord: https://discord.gg/Z9Mxu72zZ6 -- +-- -- +------------------------------------------------------------------------ +------------------------------------------------------------------------ + +config = { + -- Server name to display on the ui. + serverName = "Andy's Development", + characterLimit = 100, + changeCharacterCommand = "changecharacter", -- this is the command to open the ui again and change your character. + + -- set your backgrounds, if you have more than 1 then it will randomly change everytime you open the ui. + backgrounds = { + "https://i.imgur.com/E51ckFx.png", -- Credits: Fuzzman270#0270 + "https://i.imgur.com/SeZD7TP.png", -- Credits: Fuzzman270#0270 + "https://i.imgur.com/ZWKfYD9.png", -- Credits: 2XRondo#6374 + "https://i.imgur.com/7jM5nZT.png" -- Credits: 2XRondo#6374 + }, + + -- discord bot token for permissions + DiscordToken = "0", -- token + GuildId = "0", -- discord guild id + + -- set up your departments here, then set up the permissions for them below. + departments = { + "CIV", + "SAHP", + "LSPD", + "BCSO", + "LSFD" + }, + + -- role id for each role of the department in your discord. 0 Gives the role to everyone. + roles = { + ["ADMIN"] = "0", -- You can remove this if you don't want it but this should only be here for permisisons not as a department and it won't display as a department. This can be used for /setaop and other permissions. + ["CIV"] = "0", + ["SAHP"] = "0", + ["LSPD"] = "0", + ["BCSO"] = "0", + ["LSFD"] = "0" + }, + + -- set up the spawn buttons for each department. + spawns = { + ["CIV"] = { + {x = -102.78, y = 6336.28, z = 31.49, name = "Dream View Motel (Paleto Bay)"}, + {x = 343.53, y = 2636.94, z = 43.94, name = "Eastern Motel (Sandy Shores)"}, + {x = 196.96, y = -934.54, z = 29.69, name = "Legion Square"}, + {x = -1616.69, y = -1073.81, z = 12.15, name = "Del Perro Pier"}, + {x = -1039.65, y = -2741.02, z = 12.89, name = "LSIA"} + }, + ["SAHP"] = { + {x = -447.2, y = 6009.4, z = 30.72, name = "Paleto Bay Sheriff"}, + {x = 1849.4, y = 3688.6, z = 33.27, name = "Sandy Shores Sheriff"}, + {x = 437.6, y = -986.6, z = 29.69, name = "Mission Row PD"} + }, + ["LSPD"] = { + {x = -447.2, y = 6009.4, z = 30.72, name = "Paleto Bay Sheriff"}, + {x = 1849.4, y = 3688.6, z = 33.27, name = "Sandy Shores Sheriff"}, + {x = 437.6, y = -986.6, z = 29.69, name = "Mission Row PD"} + }, + ["BCSO"] = { + {x = -447.2, y = 6009.4, z = 30.72, name = "Paleto Bay Sheriff"}, + {x = 1849.4, y = 3688.6, z = 33.27, name = "Sandy Shores Sheriff"}, + {x = 437.6, y = -986.6, z = 29.69, name = "Mission Row Police "} + }, + ["LSFD"] = { + {x = -384.07, y = 6117.9, z = 30.48, name = "Fire Station No1 (Paleto Bay)"}, + {x = 1691.5, y = 3597.95, z = 34.56, name = "Fire Station No2 (Sandy Shores)"}, + {x = 1194.71, y = -1474.14, z = 33.86, name = "Fire Station No7 (Los Santos)"} + }, + }, + + -- Money related + payCommand = "pay", -- Command to transfer someone money from bank account. + giveCommand = "give", -- Command to give someone close money from wallet. + + salaryAmount = 300, -- the daily amount that players will receive. + salaryInterval = 24, -- every x minutes the player will receive the salaryAmount. + + -- Shot spotter related, WARNING: Shot spotter will add a 0.01 ms. + shotSpotterEnabled = true, -- will the shot spotter be enabled when a civilian shoots their weapon. + shotSpotterDelay = 5, -- delay (in seconds) when cops will receive a notification that there has been a shooting. + shotSpotterTimer = 25, -- How long should the shot spotter stay on the map. + shotSpotterCooldown = 10, -- Cooldown for the next time a player can trigger it again. + shotSpotterUsePostal = false, -- if you're using the nearest postal script turn this to true. + + enableAopCommand = true, + aopCommand = "setaop", + checkAopCommand = "aop", + defaultAop = "Unknown", + + -- Hide reticle or default gta money and ammo dispaly. WARNING: turning all to true will add a 0.01 ms. + hideReticle = true, -- hide weapon reticle. + hideAmmoAndMoney = true, -- hides the default gta ammo & money. + customPauseMenu = true, -- this will create a custom pause menu. It will display your money, characters name. And server name in the pause menu. + + -- Discord Rich precence + enableRichPrecence = true, + updateIntervall = 60, -- how many seconds delay until it updates status. + appId = 912361433273102356, + largeLogo = "anyydevlogo", + smallLogo = "anyydevlogo", + firstButtonName = "DISCORD", + firstButtonLink = "https://discord.gg/Z9Mxu72zZ6", + secondButtonName = "TEBEX", + secondButtonLink = "https://andyyy.tebex.io/category/fivem-scripts", + + -- set to true for debug mode, this will print database and some other stuff in the console. + debugMode = false +} \ No newline at end of file diff --git a/ND_Core/fxmanifest.lua b/ND_Core/fxmanifest.lua new file mode 100644 index 0000000..6471239 --- /dev/null +++ b/ND_Core/fxmanifest.lua @@ -0,0 +1,43 @@ +------------------------------------------------------------------------ +------------------------------------------------------------------------ +-- DO NOT EDIT IF YOU DON'T KNOW WHAT YOU'RE DOING -- +-- -- +-- For support join my discord: https://discord.gg/Z9Mxu72zZ6 -- +------------------------------------------------------------------------ +------------------------------------------------------------------------ + +fx_version "cerulean" +game "gta5" +lua54 "yes" + +author "Andyyy#7666" +description "ND Framework Core" +version "1.0" + +files { + "source/ui/index.html", + "source/ui/js/jquery-3.6.0.min.js", + "source/ui/js/listener.js", + "source/ui/Logo.png", + "source/ui/style.css", +} + +ui_page "source/ui/index.html" + +shared_script "config.lua" + +server_scripts { + "source/server/discord.lua", + "source/server/main.lua", + "source/server/commands.lua" +} +client_scripts { + "source/client/main.lua", + "source/client/commands.lua" +} + +exports { + "getCharacterInfo", -- getCharacterInfo(int), 1 will return return FirstName, 2 LastName, 3 DateOfBirth, 4 Gender, 5 TwtName, 6 Department, 7 Cash, 8 Bank. 9 will return their character id. + "sendBank", -- sendBank(sendingCharacterId, receiveingPlayerId, amount, sendingPlayerId) + "sendCash" -- sendCash(sendingCharacterId, amount, sendingPlayerId) +} \ No newline at end of file diff --git a/ND_Core/query.sql b/ND_Core/query.sql new file mode 100644 index 0000000..4c8726e --- /dev/null +++ b/ND_Core/query.sql @@ -0,0 +1,15 @@ +CREATE TABLE `characters` ( + `license` VARCHAR(200) NOT NULL DEFAULT '0' COLLATE 'utf8mb4_general_ci', + `character_id` INT(50) NULL DEFAULT NULL, + `first_name` VARCHAR(50) NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci', + `last_name` VARCHAR(50) NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci', + `dob` VARCHAR(50) NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci', + `gender` VARCHAR(50) NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci', + `twt` VARCHAR(50) NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci', + `department` VARCHAR(50) NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci', + `cash` INT(11) NULL DEFAULT NULL, + `bank` INT(11) NULL DEFAULT NULL +) +COLLATE='utf8mb4_general_ci' +ENGINE=InnoDB +; \ No newline at end of file diff --git a/ND_Core/source/client/commands.lua b/ND_Core/source/client/commands.lua new file mode 100644 index 0000000..4d43752 --- /dev/null +++ b/ND_Core/source/client/commands.lua @@ -0,0 +1,109 @@ +------------------------------------------------------------------------ +------------------------------------------------------------------------ +-- DO NOT EDIT IF YOU DON'T KNOW WHAT YOU'RE DOING -- +-- -- +-- For support join my discord: https://discord.gg/Z9Mxu72zZ6 -- +------------------------------------------------------------------------ +------------------------------------------------------------------------ + +-- Aop command +if config.enableAopCommand then + TriggerEvent("chat:addSuggestion", "/" .. config.aopCommand, "Change the Area of Play.", { + { name="Area", help="Area of Play" } + }) + TriggerEvent("chat:addSuggestion", "/" .. config.checkAopCommand, "Check the current Area of Play.", {}) + RegisterCommand(config.checkAopCommand, function(source, args, raw) + TriggerServerEvent("getAop") + end, false) + RegisterCommand(config.aopCommand, function(source, args, raw) + if admin == true then + TriggerServerEvent("registerAop", string.gsub(raw, config.aopCommand .. " ", "")) + else + TriggerEvent("chat:addMessage", { + args = {"~r~You don't have permission to set the aop."} + }) + end + end, false) + RegisterNetEvent("setAop") + AddEventHandler("setAop", function(aop) + SendNUIMessage({ + type = "aop", + aop = "Current AOP: " .. aop + }) + TriggerEvent("chat:addMessage", { + args = {"~b~Aop has been changed to: " .. aop} + }) + end) + RegisterNetEvent("returnAop") + AddEventHandler("returnAop", function(aop) + SendNUIMessage({ + type = "aop", + aop = "Current AOP: " .. aop + }) + TriggerEvent("chat:addMessage", { + args = {"~b~The current AOP is: " .. aop} + }) + end) +end + +-- Money commands +RegisterCommand(config.payCommand, function(source, args, raw) + sendBank(mainCharaterId, args[1], args[2], GetPlayerServerId(PlayerId())) +end) +RegisterCommand(config.giveCommand, function(source, args, raw) + sendCash(mainCharaterId, args[1], GetPlayerServerId(PlayerId())) +end) + +-- Twotter command +RegisterCommand("twt", function(source, args, rawCommand) + TriggerServerEvent("twt", GetPlayerServerId(PlayerId()), mainTwtName, string.gsub(rawCommand, "twt", "")) +end, false) +RegisterNetEvent("twt") +AddEventHandler("twt", function(id, twtName, twt) + TriggerEvent("chat:addMessage", { + template = " {0}: {1}", + multiline = true, + args = {"^4@" .. twtName .. " (#" .. id .. ")", twt} + }) +end) + +-- Me command +RegisterCommand("me", function(source, args, rawCommand) + TriggerServerEvent("me", GetPlayerServerId(PlayerId()), mainFirstName .. " " .. mainLastName, string.gsub(rawCommand, "twt", ""), GetEntityCoords(PlayerPedId())) +end, false) +RegisterNetEvent("me") +AddEventHandler("me", function(id, name, msg, coords) + if #(coords - GetEntityCoords(PlayerPedId())) < 19.999 then + TriggerEvent("chat:addMessage", { + color = {255, 0, 0}, + args = {"^*ME | ^0" .. name .. " (#" .. id .. ")", msg} + }) + end +end) + +-- Change character command +TriggerEvent("chat:addSuggestion", "/" .. config.changeCharacterCommand, "Switch your framework character.", {}) +RegisterCommand(config.changeCharacterCommand, function() + SwitchOutPlayer(PlayerPedId(), 0, 1) + Citizen.Wait(2000) + FreezeEntityPosition(ped, true) + SetEntityVisible(ped, false, 0) + SetDisplay(true, "ui") +end, false) + +-- Help command +RegisterCommand("help", function(source, args, rawCommand) + TriggerEvent("chat:addMessage", { + color = {252, 186, 3}, + args = {"^*Help | ", "/twt, /ooc, /darkweb, /me, /setAop, /aop, /pay, /give, /changecharacter"} + }) +end, false) + +-- chat suggestions +TriggerEvent("chat:addSuggestion", "/" .. config.payCommand, "Transfer money to player", {{ name="id", help="Player server id" }, { name="amount", help="amount to pay" }}) +TriggerEvent("chat:addSuggestion", "/" .. config.giveCommand, "Give money to closeby player", {{ name="amount", help="amount to give" }}) +TriggerEvent("chat:addSuggestion", "/twt", "Send a Twotter in game. (Global Chat)", {{ name="Message", help="Twotter Message."}}) +TriggerEvent("chat:addSuggestion", "/ooc", "Out Of Character chat Message. (Global Chat)", {{ name="Message", help="Put your questions or help request."}}) +TriggerEvent("chat:addSuggestion", "/darkweb", "Send a anonymous message in game. (Global Chat)", {{ name="Message", help="Anonymous Message."}}) +TriggerEvent("chat:addSuggestion", "/me", "Send message in the third person. (Proximity Chat)", {{ name="Action", help="action."}}) +TriggerEvent("chat:addSuggestion", "/help", "", {}) \ No newline at end of file diff --git a/ND_Core/source/client/main.lua b/ND_Core/source/client/main.lua new file mode 100644 index 0000000..6860bf9 --- /dev/null +++ b/ND_Core/source/client/main.lua @@ -0,0 +1,454 @@ +------------------------------------------------------------------------ +------------------------------------------------------------------------ +-- DO NOT EDIT IF YOU DON'T KNOW WHAT YOU'RE DOING -- +-- -- +-- For support join my discord: https://discord.gg/Z9Mxu72zZ6 -- +------------------------------------------------------------------------ +------------------------------------------------------------------------ + +started = true +registered = false +admin = false + +RegisterNetEvent("permsChecked") +AddEventHandler("permsChecked", function(role, rolePermission) + if rolePermission == true then + if role == "ADMIN" then + admin = true + else + SendNUIMessage({ + type = "givePerms", + deptRole = role + }) + end + end +end) + +Citizen.CreateThread(function() + while started do + Citizen.Wait(200) + local ped = PlayerPedId() + if IsPedOnFoot(ped) or IsPedInVehicle(ped, GetVehiclePedIsIn(ped, false), false) then + print("^0This framework is created by ^5Andyyy#7666 ^0for support you can join the ^5discord: ^0https://discord.gg/Z9Mxu72zZ6") + for i = 1, #config.departments do -- if you have an error that says attempt to index a nil value (global 'config') it's beacuse you have edited the config wrong. + TriggerServerEvent("checkPerms", config.departments[i]) + end + Citizen.Wait(10) + TriggerServerEvent("checkPerms", "ADMIN") + Citizen.Wait(10) + TriggerServerEvent("getCharacters") + Citizen.Wait(100) + TriggerServerEvent("getAop") + Citizen.Wait(10) + SwitchOutPlayer(ped, 0, 1) + FreezeEntityPosition(ped, true) + SetEntityVisible(ped, false, 0) + started = false + end + end +end) + +RegisterNUICallback("exitGame", function(data) + TriggerServerEvent("exitGame", GetPlayerServerId(PlayerId())) +end) + +RegisterNetEvent("returnCharacters") +AddEventHandler("returnCharacters", function(characters) + for i = 1, #characters do + index = characters[i] + if config.debugMode then + print(index.id .. " " .. index.firstName .. " " .. index.lastName .. " " .. index.dob .. " " .. index.gender .. index.twt .. " " .. index.department .. " " .. index.cash .. " " .. index.bank) + end + SendNUIMessage({ + type = "character", + id = index.id, + firstName = index.firstName, + lastName = index.lastName, + dateOfBirth = index.dob, + gender = index.gender, + twtName = index.twt, + department = index.department, + startingCash = index.cash, + startingBank = index.bank + }) + end + characterAmount = #characters + if config.debugMode then + print("Characters: " .. characterAmount .. "/" .. config.characterLimit) + end + SetDisplay(true, "ui") +end) + +RegisterNUICallback("newCharacter", function(data) + if characterAmount < config.characterLimit then + newCharacter = { + firstName = data.firstName, + lastName = data.lastName, + dateOfBirth = data.dateOfBirth, + gender = data.gender, + twtName = data.twtName, + department = data.department, + startingCash = data.startingCash, + startingBank = data.startingBank + } + TriggerServerEvent("newCharacter", newCharacter) + end +end) + +RegisterNetEvent("returnNewCharacter") +AddEventHandler("returnNewCharacter", function(id, character) + characterAmount = characterAmount +1 + SendNUIMessage({ + type = "character", + id = character.id, + firstName = character.firstName, + lastName = character.lastName, + dateOfBirth = character.dob, + gender = character.gender, + twtName = character.twt, + department = character.department, + startingCash = character.cash, + startingBank = character.bank, + characterAmount = characterAmount .. "/" .. config.characterLimit + }) +end) + +RegisterNUICallback("editCharacter", function(data) + newCharacter = { + firstName = data.firstName, + lastName = data.lastName, + dateOfBirth = data.dateOfBirth, + gender = data.gender, + twtName = data.twtName, + department = data.department, + --startingCash = data.startingCash, + --startingBank = data.startingBank, + id = data.id + } + TriggerServerEvent("editCharacter", newCharacter) +end) + +RegisterNUICallback("delCharacter", function(data) + TriggerServerEvent("delCharacter", data.character) + characterAmount = characterAmount -1 + SendNUIMessage({ + characterAmount = characterAmount .. "/" .. config.characterLimit + }) +end) + +RegisterNUICallback("setMainCharacter", function(data) + mainFirstName = data.firstName + mainLastName = data.lastName + mainDateOfBirth = data.dateOfBirth + mainGender = data.gender + mainTwtName = data.twtName + mainDepartment = data.department + mainStartingCash = data.startingCash + mainStartingBank = data.startingBank + mainCharaterId = data.character + + if config.debugMode then + for k, v in pairs(data) do + print(v) + end + end + + for i = 1, #config.departments do + validDept = config.departments[i] + if mainDepartment == validDept then + for i = 1, #config.spawns[validDept] do + SendNUIMessage({ + type = "setSpawns", + x = config.spawns[validDept][i].x, + y = config.spawns[validDept][i].y, + z = config.spawns[validDept][i].z, + name = config.spawns[validDept][i].name + }) + end + end + end + + registered = true +end) + +RegisterNetEvent("returnMoney") +AddEventHandler("returnMoney", function(cash, bank) + while not registered do + Citizen.Wait(100) + end + cash = cash + bank = bank + SendNUIMessage({ + type = "Money", + cash = "Cash: $" .. cash, + bank = "Bank: $" .. bank + }) +end) + +RegisterNUICallback("tpToLocation", function(data) + local ped = PlayerPedId() + FreezeEntityPosition(ped, false) + SetEntityCoords(ped, tonumber(data.x), tonumber(data.y), tonumber(data.z), false, false, false, false) + FreezeEntityPosition(ped, true) + SwitchInPlayer(ped) + Citizen.Wait(500) + SetDisplay(false, "ui") + Citizen.Wait(500) + FreezeEntityPosition(ped, false) + SetEntityVisible(ped, true, 0) + TriggerServerEvent("getMoney", mainCharaterId) +end) + +RegisterNUICallback("tpDoNot", function(data) + local ped = PlayerPedId() + SwitchInPlayer(ped) + Citizen.Wait(500) + SetDisplay(false, "ui") + Citizen.Wait(500) + SetEntityVisible(ped, true, 0) + FreezeEntityPosition(ped, false) + TriggerServerEvent("getMoney", mainCharaterId) +end) + +function SetDisplay(bool, typeName) + SetNuiFocus(bool, bool) + SendNUIMessage({ + type = typeName, + background = config.backgrounds[math.random(1, #config.backgrounds)], + status = bool, + serverName = config.serverName, + characterAmount = characterAmount .. "/" .. config.characterLimit + }) +end + +if config.enableRichPrecence == true then + Citizen.CreateThread(function() + while true do + Citizen.Wait(config.updateIntervall * 1000) + SetDiscordAppId(config.appId) + if registered == true then + SetRichPresence(" Playing : " .. config.serverName .. " as " .. mainFirstName .. " " .. mainLastName) + SetDiscordRichPresenceAsset(config.largeLogo) + SetDiscordRichPresenceAssetText("Playing: " .. config.serverName) + SetDiscordRichPresenceAssetSmall(config.smallLogo) + SetDiscordRichPresenceAssetSmallText("Playing as: " .. mainFirstName .. " " .. mainLastName) + SetDiscordRichPresenceAction(0, config.firstButtonName, config.firstButtonLink) + SetDiscordRichPresenceAction(1, config.secondButtonName, config.secondButtonLink) + end + end + end) +end + +-- Shot spotter +if config.shotSpotterEnabled then + local activateShotSpotter = false + local alreadyShot = false + RegisterNetEvent("shotSpotterReport") + AddEventHandler("shotSpotterReport", function(x, y, z, postal) + if registered then + if mainDepartment == "SAHP" or mainDepartment == "LSPD" or mainDepartment == "BCSO" then + activateShotSpotter = true + while activateShotSpotter do + Citizen.Wait(0) + blip = AddBlipForCoord(x, y, z) + SetBlipSprite(blip, 161) + SetBlipAsShortRange(blip, true) + BeginTextCommandSetBlipName("STRING") + AddTextComponentString("Shot Spotter") + EndTextCommandSetBlipName(blip) + if not postal then + msg = "~r~Dispatch: ~w~Shotspotter detected in " .. GetStreetNameFromHashKey(GetStreetNameAtCoord(x, y, z)) .. "." + else + msg = "~r~Dispatch: ~w~Shotspotter detected in " .. GetStreetNameFromHashKey(GetStreetNameAtCoord(x, y, z)) .. ", postal: " .. postal .. "." + end + TriggerEvent('chat:addMessage', { + args = {msg} + }) + Citizen.Wait(config.shotSpotterTimer * 1000) + activateShotSpotter = false + break + end + RemoveBlip(blip) + end + end + end) + Citizen.CreateThread(function() + while true do + Citizen.Wait(0) + local ped = PlayerPedId() + if registered then + if mainDepartment == "CIV" then + if IsPedShooting(ped) then + if not alreadyShot then + Citizen.Wait(config.shotSpotterDelay * 1000) + pedCoords = GetEntityCoords(ped) + if config.shotSpotterUsePostal then + postal = exports["nearest_postal123"]:getPostal() + else + postal = false + end + TriggerServerEvent("shotSpotterActive", pedCoords.x, pedCoords.y, pedCoords.z, postal) + if config.debugMode then + print(pedCoords.x, pedCoords.y, pedCoords.z) + end + end + alreadyShot = true + Citizen.Wait(config.shotSpotterCooldown * 1000) + alreadyShot = false + end + end + end + end + end) +end + +-- hide gta default cash, ammo and reticle hud. +if config.hideAmmoAndMoney == true or config.hideReticle == true then + Citizen.CreateThread(function() + while true do + Citizen.Wait(0) + if config.hideAmmoAndMoney == true then + HideHudComponentThisFrame(3) -- CASH + HideHudComponentThisFrame(4) -- MP_CASH + HideHudComponentThisFrame(13) -- CASH_CHANGE + HideHudComponentThisFrame(2) -- WEAPON_ICON + end + if config.hideReticle == true then + --if IsPlayerFreeAiming(PlayerPedId()) then + HideHudComponentThisFrame(14) -- RETICLE + --end + end + if config.customPauseMenu then + if registered then + if IsPauseMenuActive() then + BeginScaleformMovieMethodOnFrontendHeader("SET_HEADING_DETAILS") + AddTextEntry("FE_THDR_GTAO", config.serverName) + ScaleformMovieMethodAddParamPlayerNameString(mainFirstName .. " " .. mainLastName) + --PushScaleformMovieFunctionParameterString("Cash: $" .. cash) + --PushScaleformMovieFunctionParameterString("Bank: $" .. bank) + EndScaleformMovieMethod() + end + end + end + end + end) +end + +RegisterNetEvent("receiveBank") +AddEventHandler("receiveBank", function(amount, playerSending, name) + if config.debugMode then + print("Recived $" .. amount .. " from " .. name .. " [".. playerSending .."]") + end + SetNotificationTextEntry("STRING") + AddTextComponentString("Recived $" .. amount .. " from " .. name .. " [".. playerSending .."]") + SetNotificationMessage("CHAR_BANK_FLEECA", "CHAR_BANK_FLEECA", true, 9,"FleecaBank", "") + TriggerServerEvent("addBank", amount, mainCharaterId) +end) + +RegisterNetEvent("receiveCash") +AddEventHandler("receiveCash", function(amount, playerSending, name) + if config.debugMode then + print("Recived $" .. amount .. " from " .. name .. " [".. playerSending .."]") + end + SetNotificationTextEntry("STRING") + AddTextComponentString(name .. " gave you $" .. amount .. ".") + SetNotificationMessage("CHAR_DEFAULT", "CHAR_DEFAULT", true, 9, name .. " [".. playerSending .."]", "") + TriggerServerEvent("addCash", amount, mainCharaterId) +end) + +RegisterNetEvent("updateMoney") +AddEventHandler("updateMoney", function() + TriggerServerEvent("getMoney", mainCharaterId) +end) + +Citizen.CreateThread(function() + while true do + Citizen.Wait(config.salaryInterval * 60000) + if registered then + TriggerServerEvent("addBank", config.salaryAmount, mainCharaterId) + SetNotificationTextEntry("STRING") + AddTextComponentString("Daily Salary + $" .. config.salaryAmount) + SetNotificationMessage("CHAR_BANK_FLEECA", "CHAR_BANK_FLEECA", true, 9,"FleecaBank", "") + end + end +end) + +function sendBank(sendingCharacterId, receiveingPlayerId, amount, sendingPlayerId) + if registered then + TriggerServerEvent("bankPay", sendingCharacterId, receiveingPlayerId, amount, sendingPlayerId, mainFirstName .. " " .. mainLastName) + end +end + +function sendCash(sendingCharacterId, amount, sendingPlayerId) + if registered then + target, distance = GetClosestPlayer() + if (distance ~= -1 and distance < 3) then + TriggerServerEvent("cashPay", sendingCharacterId, GetPlayerServerId(target), amount, sendingPlayerId, mainFirstName .. " " .. mainLastName) + else + notify("No players nearby") + end + end +end + +function notify(message) + SetNotificationTextEntry("STRING") + AddTextComponentString(message) + DrawNotification(0,1) +end + +function GetClosestPlayer() + local players = GetPlayers() + local closestDistance = -1 + local closestPlayer = -1 + local ply = GetPlayerPed(-1) + local plyCoords = GetEntityCoords(ply, 0) + + for index,value in ipairs(players) do + local target = GetPlayerPed(value) + if(target ~= ply) then + local targetCoords = GetEntityCoords(GetPlayerPed(value), 0) + local distance = GetDistanceBetweenCoords(targetCoords["x"], targetCoords["y"], targetCoords["z"], plyCoords["x"], plyCoords["y"], plyCoords["z"], true) + if(closestDistance == -1 or closestDistance > distance) then + closestPlayer = value + closestDistance = distance + end + end + end + return closestPlayer, closestDistance +end + +function GetPlayers() + local players = {} + + for i = 0, 255 do + if NetworkIsPlayerActive(i) then + table.insert(players, i) + end + end + + return players +end + +function getCharacterInfo(int) + if registered then + if int == 1 then + return mainFirstName + elseif int == 2 then + return mainLastName + elseif int == 3 then + return mainDateOfBirth + elseif int == 4 then + return mainGender + elseif int == 5 then + return mainTwtName + elseif int == 6 then + return mainDepartment + elseif int == 7 then + return mainStartingCash + elseif int == 8 then + return mainStartingBank + elseif int == 9 then + return mainCharaterId + end + end +end \ No newline at end of file diff --git a/ND_Core/source/server/commands.lua b/ND_Core/source/server/commands.lua new file mode 100644 index 0000000..13386ac --- /dev/null +++ b/ND_Core/source/server/commands.lua @@ -0,0 +1,52 @@ +------------------------------------------------------------------------ +------------------------------------------------------------------------ +-- DO NOT EDIT IF YOU DON'T KNOW WHAT YOU'RE DOING -- +-- -- +-- For support join my discord: https://discord.gg/Z9Mxu72zZ6 -- +------------------------------------------------------------------------ +------------------------------------------------------------------------ + +-- Aop command +if config.enableAopCommand then + RegisterNetEvent("registerAop") + AddEventHandler("registerAop", function(aopRegistered) + aop = aopRegistered + TriggerClientEvent("setAop", -1, aop) + end) + RegisterNetEvent("getAop") + AddEventHandler("getAop", function() + local player = source + if aop == nil then + aop = config.defaultAop + end + TriggerClientEvent("returnAop", player, aop) + end) +end + +-- Twotter command +RegisterNetEvent("twt") +AddEventHandler("twt", function(id, twtName, twt) + TriggerClientEvent("twt", -1, id, twtName, twt) +end) + +-- Me command +RegisterNetEvent("me") +AddEventHandler("me", function(id, name, msg, coords) + TriggerClientEvent("me", -1, id, name, msg, coords) +end) + +-- OOC command +RegisterCommand("ooc", function(source, args, rawCommand) + TriggerClientEvent("chat:addMessage", -1, { + color = {150, 150, 150}, + args = {"^*OOC | ^0" .. GetPlayerName(source) .. " (#" .. source .. ")", string.gsub(rawCommand, "ooc", "")} + }) +end, false) + +-- Darkweb command +RegisterCommand("darkweb", function(source, args, rawCommand) + TriggerClientEvent("chat:addMessage", -1, { + color = {0, 0, 0}, + args = {"^*Dark web | ^0Anonymous (#" .. source .. ")", string.gsub(rawCommand, "darkweb", "")} + }) +end, false) \ No newline at end of file diff --git a/ND_Core/source/server/discord.lua b/ND_Core/source/server/discord.lua new file mode 100644 index 0000000..fd93569 --- /dev/null +++ b/ND_Core/source/server/discord.lua @@ -0,0 +1,100 @@ +-- original discord roles author: https://forum.cfx.re/t/discord-roles-for-permissions-im-creative-i-know/233805?u=andyyy7666 +local FormattedToken = "Bot "..config.DiscordToken + +function DiscordRequest(method, endpoint, jsondata) + local data = nil + PerformHttpRequest("https://discordapp.com/api/"..endpoint, function(errorCode, resultData, resultHeaders) + data = {data=resultData, code=errorCode, headers=resultHeaders} + end, method, #jsondata > 0 and json.encode(jsondata) or "", {["Content-Type"] = "application/json", ["Authorization"] = FormattedToken}) + + while data == nil do + Citizen.Wait(0) + end + + return data +end + + --[[ we don't use this in this resource. +function GetRoles(user) + local discordId = nil + for _, id in ipairs(GetPlayerIdentifiers(user)) do + if string.match(id, "discord:") then + discordId = string.gsub(id, "discord:", "") + print("Found discord id: "..discordId) + break + end + end + + if discordId then + local endpoint = ("guilds/%s/members/%s"):format(config.GuildId, discordId) + local member = DiscordRequest("GET", endpoint, {}) + if member.code == 200 then + local data = json.decode(member.data) + local roles = data.roles + local found = true + return roles + else + print("Error occurred, maybe they are not in discord?") + return false + end + else + print("missing identifier") + return false + end +end +]] + +function IsRolePresent(user, role) + local discordId = nil + for _, id in ipairs(GetPlayerIdentifiers(user)) do + if string.match(id, "discord:") then + discordId = string.gsub(id, "discord:", "") + print("Found discord id: "..discordId) + break + end + end + + local theRole = nil + if type(role) == "number" then + theRole = tostring(role) + else + theRole = config.roles[role] + end + + if theRole == "0" then + print("Role Given (0 in config)") + return true + elseif discordId then + local endpoint = ("guilds/%s/members/%s"):format(config.GuildId, discordId) + local member = DiscordRequest("GET", endpoint, {}) + if member.code == 200 then + local data = json.decode(member.data) + local roles = data.roles + local found = true + for i=1, #roles do + if roles[i] == theRole then + print("Found role") + return true + end + end + print("Not found!") + return false + else + print("Error occurred, maybe they are not in discord?") + return false + end + else + print("missing identifier") + return false + end +end + +Citizen.CreateThread(function() + local guild = DiscordRequest("GET", "guilds/"..config.GuildId, {}) + if guild.code == 200 then + local data = json.decode(guild.data) + print("Permission system guild set to: "..data.name.." ("..data.id..")") + else + print("An error occured, please check your config and ensure everything is correct. Error: "..(guild.data or guild.code)) + end +end) \ No newline at end of file diff --git a/ND_Core/source/server/main.lua b/ND_Core/source/server/main.lua new file mode 100644 index 0000000..58fb4e7 --- /dev/null +++ b/ND_Core/source/server/main.lua @@ -0,0 +1,154 @@ +------------------------------------------------------------------------ +------------------------------------------------------------------------ +-- DO NOT EDIT IF YOU DON'T KNOW WHAT YOU'RE DOING -- +-- -- +-- For support join my discord: https://discord.gg/Z9Mxu72zZ6 -- +------------------------------------------------------------------------ +------------------------------------------------------------------------ + +RegisterNetEvent("checkPerms") +AddEventHandler("checkPerms", function(role) + local player = source + local role = role + local rolePermission = IsRolePresent(player, role) + TriggerClientEvent("permsChecked", player, role, rolePermission) +end) + +RegisterNetEvent("exitGame") +AddEventHandler("exitGame", function(Player) + DropPlayer(Player, "Disconnected using framework.") +end) + +RegisterNetEvent("getCharacters") +AddEventHandler("getCharacters", function() + local player = source + local license = GetPlayerIdentifier(player, 1) + exports.oxmysql:execute("SELECT * FROM characters WHERE license = ?", {license}, function(result) + if result then + characters = {} + for i = 1, #result do + temp = result[i] + table.insert(characters, {id = temp.character_id, firstName = temp.first_name, lastName = temp.last_name, dob = temp.dob, gender = temp.gender, twt = temp.twt, department = temp.department, cash = temp.cash, bank = temp.bank}) + end + TriggerClientEvent("returnCharacters", player, characters) + end + end) +end) + +RegisterNetEvent("newCharacter") +AddEventHandler("newCharacter", function(newCharacter) + local player = source + local license = GetPlayerIdentifier(player, 1) + exports.oxmysql:execute("SELECT MAX(character_id) AS nextID FROM characters WHERE license LIKE ?", {license}, function(result) + if result then + character_id = result[1].nextID + if character_id == nil then + character_id = 1 + else + character_id = character_id + 1 + end + exports.oxmysql:execute("INSERT INTO characters (license, character_id, first_name, last_name, dob, gender, twt, department, cash, bank) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", {license, character_id, newCharacter.firstName, newCharacter.lastName, newCharacter.dateOfBirth, newCharacter.gender, newCharacter.twtName, newCharacter.department, newCharacter.startingCash, newCharacter.startingBank}, function(id) + if id then + TriggerClientEvent("returnNewCharacter", player, id, newCharacter) + end + end) + end + end) +end) + +RegisterNetEvent("delCharacter") +AddEventHandler("delCharacter", function(character_id) + local player = source + local license = GetPlayerIdentifier(player, 1) + exports.oxmysql:execute("DELETE FROM characters WHERE license LIKE ? AND character_id LIKE ?", {license, character_id}, function(id) + if id then + print(id) + end + end) +end) + +RegisterNetEvent("editCharacter") +AddEventHandler("editCharacter", function(newCharacter) + local player = source + local license = GetPlayerIdentifier(player, 1) + exports.oxmysql:execute("UPDATE characters SET first_name = ?, last_name = ?, dob = ?, gender = ?, twt = ?, department = ? WHERE license = ? AND character_id = ?", {newCharacter.firstName, newCharacter.lastName, newCharacter.dateOfBirth, newCharacter.gender, newCharacter.twtName, newCharacter.department, license, newCharacter.id}, function(id) + if id then + print(id) + end + end) +end) + +if config.shotSpotterEnabled then + RegisterNetEvent("shotSpotterActive") + AddEventHandler("shotSpotterActive", function(x, y, z, postal) + TriggerClientEvent("shotSpotterReport", -1, x, y, z, postal) + end) +end + +RegisterNetEvent("bankPay") +AddEventHandler("bankPay", function(characterid, playerid, amount, playerSending, name) + local player = source + local license = GetPlayerIdentifier(player, 1) + exports.oxmysql:execute("UPDATE characters SET bank = bank - ? WHERE license = ? AND character_id = ?", {amount, license, characterid}, function(bank) + if bank then + print(bank) + end + end) + TriggerClientEvent("receiveBank", playerid, amount, playerSending, name) + TriggerClientEvent("updateMoney", player) +end) + +RegisterNetEvent("addBank") +AddEventHandler("addBank", function(amount, characterid) + local player = source + license = GetPlayerIdentifier(player, 1) + exports.oxmysql:execute("UPDATE characters SET bank = bank + ? WHERE license = ? AND character_id = ?", {amount, license, characterid}, function(bank) + if bank then + print(bank) + end + end) + TriggerClientEvent("updateMoney", player) +end) + +RegisterNetEvent("cashPay") +AddEventHandler("cashPay", function(characterid, playerid, amount, playerSending, name) + local player = source + local license = GetPlayerIdentifier(player, 1) + exports.oxmysql:execute("UPDATE characters SET cash = cash - ? WHERE license = ? AND character_id = ?", {amount, license, characterid}, function(cash) + if cash then + print(cash) + end + end) + TriggerClientEvent("receiveCash", playerid, amount, playerSending, name) + TriggerClientEvent("updateMoney", player) +end) + +RegisterNetEvent("addCash") +AddEventHandler("addCash", function(amount, characterid) + local player = source + local license = GetPlayerIdentifier(player, 1) + exports.oxmysql:execute("UPDATE characters SET cash = cash + ? WHERE license = ? AND character_id = ?", {amount, license, characterid}, function(cash) + if cash then + print(cash) + end + end) + TriggerClientEvent("updateMoney", player) +end) + +RegisterNetEvent("getMoney") +AddEventHandler("getMoney", function(characterid) + local player = source + local license = GetPlayerIdentifier(player, 1) + exports.oxmysql:execute("SELECT cash, bank FROM characters WHERE license = ? AND character_id = ?", {license, characterid}, function(result) + if result then + for i = 1, #result do + cash = result[i].cash + bank = result[i].bank + print(cash) + print(bank) + end + end + end) + Citizen.Wait(300) + TriggerClientEvent("returnMoney", player, cash, bank) +end) \ No newline at end of file diff --git a/ND_Core/source/ui/Logo.png b/ND_Core/source/ui/Logo.png new file mode 100644 index 0000000000000000000000000000000000000000..9111d35eac3f4f29103da8a4347c2a83ffcf0573 GIT binary patch literal 23945 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 B>{0*# literal 0 HcmV?d00001 diff --git a/ND_Core/source/ui/index.html b/ND_Core/source/ui/index.html new file mode 100644 index 0000000..cb455db --- /dev/null +++ b/ND_Core/source/ui/index.html @@ -0,0 +1,180 @@ + + + + + + + + + + + + + +

+
+ +
+
+

+

+

Select or create a character:

+
+
+ +
+ +
+
+
+
+ + +
+
+

Character Creation

+
+
+
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+
+
+ + +
+
+ + +
+
+

Character Editor

+
+
+
+
+ + + + +
+
+ + + + +
+
+ + + + +
+ +
+
+
+ + +
+
+ + +
+
+

Spawn Location

+
+
+
+
+
+
+ + +
+
+ + +
+

Are you sure you'd like to quit the game?

+
+ + +
+ + +
+

Are you sure you'd like to delete this character?

+
+ + +
+ + +
+

+

+
+ + \ No newline at end of file diff --git a/ND_Core/source/ui/js/jquery-3.6.0.min.js b/ND_Core/source/ui/js/jquery-3.6.0.min.js new file mode 100644 index 0000000..200b54e --- /dev/null +++ b/ND_Core/source/ui/js/jquery-3.6.0.min.js @@ -0,0 +1,2 @@ +/*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0', { + text: item.deptRole + })); + } + + if (item.type === "aop") { + $("#aop").text(item.aop); + } + + if (item.type === "Money") { + Money(true) + $("#cash").text(item.cash); + $("#bank").text(item.bank); + } + }) + + function createCharacter(firstName, lastName, dateOfBirth, gender, twtName, department, startingCash, startingBank, id) { + $("#charactersSection").append(''); + $("#characterButton" + id).click(function() { + spawnMenu(true) + $.post("https://ND_Core/setMainCharacter", JSON.stringify({ + firstName: firstName, + lastName: lastName, + dateOfBirth: dateOfBirth, + gender: gender, + twtName: twtName, + department: department, + startingCash: startingCash, + startingBank: startingBank, + character: id + })); + return + }) + $("#characterButtonEdit" + id).click(function() { + characterEditorMenu(true) + characterEdited = id + return + }) + $("#characterButtonDelete" + id).click(function() { + confirmDeleteMenu(true) + characterDeleting = id + return + }) + } + + /* + function tp(x, y, z, name) { + $.post("https://ND_Core/tpToLocation", JSON.stringify({ + x: x, + y: y, + z: z, + name: name + })); + spawnMenu(false) + setTimeout(function(){ + $("#spawnMenuContainer").empty(); + }, 550); + return + } + */ + + function createSpawnButtons(x, y, z, name) { + $("#spawnMenuContainer").empty(); + setTimeout(function(){ + $("#spawnMenuContainer").append(``); + }, 10); + } + + $("#characterCreator").submit(function() { + $.post("https://ND_Core/newCharacter", JSON.stringify({ + firstName: $("#firstName").val(), + lastName: $("#lastName").val(), + dateOfBirth: $("#dateOfBirth").val(), + gender: $("#gender").val(), + twtName: $("#twtName").val(), + department: $("#department").val(), + startingCash: $("#startingCash").val(), + startingBank: $("#startingBank").val() + })); + characterCreatorMenu(false) + return false + }) + + $("#characterEditor").submit(function() { + characterEditorMenu(false) + $.post("https://ND_Core/editCharacter", JSON.stringify({ + firstName: $("#newFirstName").val(), + lastName: $("#newLastName").val(), + dateOfBirth: $("#newDateOfBirth").val(), + gender: $("#newGender").val(), + twtName: $("#newTwtName").val(), + department: $("#newDepartment").val(), + //startingCash: $("#newStartingCash").val(), + //startingBank: $("#newStartingBank").val(), + id: characterEdited + })); + $("#characterButton" + characterEdited).text($("#newFirstName").val() + " " + $("#newLastName").val() + " (" + $("#newDepartment").val() + ")"); + return false + }) + + $("#deleteCharacterConfirm").click(function() { + confirmDeleteMenu(false) + $("#characterButton" + characterDeleting).fadeOut("slow",function(){ + $("#characterButton" + characterDeleting).remove(); + }) + $("#characterButtonEdit" + characterDeleting).fadeOut("slow",function(){ + $("#characterButtonEdit" + characterDeleting).remove(); + }) + $("#characterButtonDelete" + characterDeleting).fadeOut("slow",function(){ + $("#characterButtonDelete" + characterDeleting).remove(); + }) + $.post("https://ND_Core/delCharacter", JSON.stringify({ + character: characterDeleting + })); + return + }) + + $("#newCharacterButton").click(function() { + characterCreatorMenu(true) + return + }) + + $("#deleteCharacterCancel").click(function() { + confirmDeleteMenu(false) + return + }) + $("#cancelCharacterCreation").click(function() { + characterCreatorMenu(false) + return + }) + $("#cancelCharacterEditing").click(function() { + characterEditorMenu(false) + return + }) + + $("#tpCancel").click(function() { + spawnMenu(false) + setTimeout(function(){ + $("#spawnMenuContainer").empty(); + }, 550); + return + }) + $("#tpDoNot").click(function() { + $.post("https://ND_Core/tpDoNot", JSON.stringify({ + test: "test" + })); + spawnMenu(false) + setTimeout(function(){ + $("#spawnMenuContainer").empty(); + }, 550); + return + }) + + $("#quitGameButton").click(function() { + exitGameMenu(true) + return + }) + $("#exitGameCancel").click(function() { + exitGameMenu(false) + return + }) + $("#exitGameConfirm").click(function() { + $.post("https://ND_Core/exitGame", JSON.stringify({})); + return + }) +}); \ No newline at end of file diff --git a/ND_Core/source/ui/style.css b/ND_Core/source/ui/style.css new file mode 100644 index 0000000..c4efb1b --- /dev/null +++ b/ND_Core/source/ui/style.css @@ -0,0 +1,281 @@ +body { + background-size: 105%; + background-repeat: no-repeat; + background-attachment: fixed; + background-position: center; +} + +/* Main page */ +#overlay { + top: 0px; + left: 0px; + height: 100vh; + width: 30vw; + background-color: rgba(2, 2, 2, 0.911); + position: fixed; +} + +#charactersSection { + height: 50%; + margin: none; + padding: none; + width: 83%; + overflow-y: scroll; +} + +::-webkit-scrollbar { + width: 10px; +} +::-webkit-scrollbar-track { + background: rgba(2, 2, 2, 0); +} +::-webkit-scrollbar-thumb { + background: rgba(99, 99, 99, 0.575); + border-radius: 10px; +} +::-webkit-scrollbar-thumb:hover { + background: rgb(128, 128, 128); + border-radius: 10px; +} + +#logoContainer { + margin-top: 3vh; + margin-left: 10vw; +} +#logo { + height: 10vw; + width: 10vw; +} + +#serverName { + color: white; + font-size: 130%; + font-family: Verdana, Geneva, Tahoma, sans-serif; + text-align: center; + font-weight: bolder; +} + +.mainPage { + color: white; + font-size: 95%; + font-family: Verdana, Geneva, Tahoma, sans-serif; + text-align: center; + font-weight: lighter; +} + +.homeScreenButton, .createdButton, .createdButtonEdit, .createdButtonDelete { + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; + font-weight: bold; + text-align: center; + border: none; + color: white; +} + +#newCharacterButton { + margin-left: 9vw; + margin-bottom: 0.8vh; + height: 4.5vh; + width: 12vw; + background: rgb(95,141,254); + background-image: linear-gradient(90deg, rgba(95,141,254,1) 0%, rgba(142,104,219,1) 100%); + border-radius: 5vw; + transition: 0.3s; +} + +#quitGameButton { + margin-left: 10vw; + margin-bottom: 5vh; + height: 4.5vh; + width: 10vw; + background: rgb(255,110,100); + background: linear-gradient(90deg, rgb(255, 100, 208) 0%, rgb(255, 60, 109) 100%); + border-radius: 5vw; + transition: 0.3s; +} + +.createdButton { + display: inline-block; + margin-bottom: 1vh; + margin-left: 5.5vw; + height: 3vh; + width: 10vw; + background-color: rgb(17, 113, 238); + border: none; + border-radius: 0.5vh; + transition: 0.3s; +} + +.createdButtonEdit { + margin-left: 0.2vw; + height: 3vh; + width: 4vw; + background-color: rgb(128, 128, 128); + border: none; + border-radius: 0.5vh; + transition: 0.3s; +} + +.createdButtonDelete { + margin-left: 0.2vw; + height: 3vh; + width: 4vw; + background-color: rgb(236, 19, 19); + border: none; + border-radius: 0.5vh; + transition: 0.3s; +} + +/* Button transitions */ +#newCharacterButton:hover, #quitGameButton:hover, .characterSubmitButton:hover, .characterResetButton:hover, .confirmationScreenConfirm:hover, .confirmationScreenCancel:hover, .createdButton:hover, .createdButtonEdit:hover, .createdButtonDelete:hover, .spawnButtons:hover { + transition: 0.3s; + opacity: 0.7; +} +#newCharacterButton:active, #quitGameButton:active, .characterSubmitButton:active, .characterResetButton:active, .confirmationScreenConfirm:active, .confirmationScreenCancel:active, .createdButton:active, .createdButtonEdit:active, .createdButtonDelete:active, .spawnButtons:active { + transition: none; + opacity: 1; +} + +/* Character creator and Editor menu */ +.characterMenu { + height: 60%; + width: 50vw; + margin-top: 15vh; + margin-left: 40vw; + background-color: rgba(2, 2, 2, 0.911); + border-radius: 3vh; +} + +#characterCreatorTopText { + padding-top: 2vh; + margin-left: 3vw; + color: white; + font-size: 120%; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; + font-weight: bold; +} + +#characterCreatorTopTextLine { + background: rgb(255, 255, 255); + background: linear-gradient(90deg, rgba(0,0,0,1) 0%, rgba(255,255,255,1) 15%, rgba(255,255,255,1) 85%, rgba(0,0,0,1) 100%); + height: 0.1vh; + width: 95%; + border: none; + border-radius: 2vh; +} + +/* character info */ +#characterInfoContainer { + margin-top: 2vh; + margin-left: 6.5vw; +} + +.firstRowText, .secondRowText, .thirdRowText, .fourthRowText { + color: white; + display: inline-block; + margin-top: 2vh; + margin-bottom: 1vh; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; + font-weight: bold; +} + +.firstRowInput, .secondRowInput, .thirdRowInput, .fourthRowInput { + background: white; + color: black; + display: inline-block; + border: none; + border-radius: 0.2vw; + height: 4vh; + width: 36%; +} + +.characterSubmitButton { + margin-top: 1vh; + margin-left: 30.3vw; + margin-bottom: 2vh; + width: 8vw; + background-color: rgb(17, 113, 238); +} + +.characterResetButton { + width: 4vw; + background-color: rgb(231, 50, 50); +} + +.characterSubmitButton, .characterResetButton, .confirmationScreenConfirm, .confirmationScreenCancel, .spawnButtons { + height: 4vh; + color: white; + font-weight: bold; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; + border: none; + border-radius: 1vh; + transition: 0.3s; +} + +/* confirmation Screen */ +.confirmationScreen { + height: 25vh; + width: 30vw; + margin-top: 20vh; + margin-left: 45vw; + background-color: rgba(2, 2, 2, 0.911); + border-radius: 3vh; +} + +.confirmationScreenConfirm { + margin-top: 5vh; + margin-left: 19%; + margin-right: 5%; + width: 8vw; + background-color: rgb(17, 113, 238); +} + +.confirmationScreenCancel { + width: 8vw; + background-color: rgb(231, 50, 50); +} + +.spawnMenu { + height: 39%; + width: 40vw; + margin-top: 15vh; + margin-left: 40vw; + background-color: rgba(2, 2, 2, 0.911); + border-radius: 3vh; +} + +#spawnMenuContainer { + margin-top: 3vh; + margin-left: 5%; +} + +.spawnButtons { + display: block; + margin-left: 0; + margin-bottom: 1vh; + text-align: center; + width: 95%; + height: 4vh; + background-color: rgb(17, 113, 238); +} + +.text { + font-family: "Pricedown Bl", sans-serif; + position: absolute; + font-size: 1vw; + color: rgba(255, 255, 255, 0.925); + margin: auto; + text-align: center; + padding: 0.15% 1.1%; + background-color: rgba(2, 2, 2, 0.548); + border-radius: 10vw; +} + +#cash { + top: 5.5vh; + right: 1.5vw; +} + +#bank { + top: 9vh; + right: 1.5vw; +} \ No newline at end of file