function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, weight, job, job2, loadout, name, coords, citizenId, discord, steamname, level, invoices) local targetOverrides = Config.PlayerFunctionOverride and Core.PlayerFunctionOverrides[Config.PlayerFunctionOverride] or {} local self = {} self.accounts = accounts self.coords = coords self.group = group self.identifier = identifier self.inventory = inventory self.job = job self.job2 = job2 self.loadout = loadout self.name = name self.citizenId = citizenId self.playerId = playerId self.source = playerId self.variables = {} self.weight = weight self.discord = discord self.steamname = steamname self.maxWeight = Config.MaxWeight self.exp = level self.invoices = invoices and invoices or {} if Config.Multichar then self.license = 'license'.. identifier:sub(identifier:find(':'), identifier:len()) else self.license = 'license:'..identifier end ExecuteCommand(('add_principal identifier.%s group.%s'):format(self.identifier, self.group)) function self.setCoords(coords) self.updateCoords(coords) self.triggerEvent('esx:teleport', coords) end function self.getInvoices() return self.invoices end function self.giveInvoice(reason, value, id) local invoiceid = ESX.GetRandomString(8) while self.invoices[id] do Wait(0) invoiceid = ESX.GetRandomString(8) end self.invoices[invoiceid] = {['id'] = invoiceid, ['reason'] = reason, ['value'] = value, ['time'] = os.time()} self.showNotification('warning', 'Je hebt een factuur ontvangen, je kan deze factuur inzien via F7!') if id then local xTarget = ESX.GetPlayerFromId(id) if xTarget then self.invoices[invoiceid]['identifier'] = xTarget.identifier end end TriggerClientEvent('frp-facturen:client:add:factuur', self.source, reason, value, invoiceid, id, os.time()) end function self.payInvoiceInstant(id) if self.invoices[id] then local price = self.invoices[id]['value'] local account = self.getAccount('bank').money if (account-price) >= 0 then self.removeAccountMoney('bank', price, 'Heeft een factuur betaald [' .. self.invoices[id]['reason'] .. ']') self.invoices[id] = nil TriggerClientEvent('frp-facturen:client:remove:factuur', self.source, id, os.time()) return true else return true end end end function self.payInvoice(id) if self.invoices[id] then local price = self.invoices[id]['value'] local account = self.getAccount('bank').money if (account-price) >= 0 then self.removeAccountMoney('bank', price, 'Heeft een factuur betaald [' .. self.invoices[id]['reason'] .. ']') self.invoices[id] = nil TriggerClientEvent('frp-facturen:client:remove:factuur', self.source, id, os.time()) self.showNotification('success', 'Je hebt succesvol een factuur betaald van €' .. price .. '!') return true else self.showNotification('error', 'Je hebt niet genoeg geld om deze factuur te betalen!') return true end end end function self.getEXP() return self.exp end function self.addEXP(exp, reason) if not reason then print('[es_extended] [^3WARNING^7] Ik heb geen reden meegekregen bij het XP veranderen, zorg dat ik een reden krijg') return end local newexp = self.exp + exp --TriggerEvent('frp-logging:server:nowait:logg', self.source, 'progression', 'green', '*Speler heeft XP erbij gekregen!*\n**Totaal oud EXP:** ' .. self.exp .. ' [LEVEL: ' .. exports['es_extended']:getCurrentLevel(self.exp) .. ']\n**Totaal nieuw EXP:** ' .. newexp .. '[LEVEL: ' .. exports['es_extended']:getCurrentLevel(newexp) .. ']\n**Erbij gekregen EXP:**' .. exp .. '\n**Reden:** ' .. reason) TriggerClientEvent('frp-boilerplate:client:exp:sync', self.source, newexp, self.exp) self.exp = newexp end function self.removeEXP(exp, reason) if not reason then print('[es_extended] [^3WARNING^7] Ik heb geen reden meegekregen bij het XP veranderen, zorg dat ik een reden krijg') return end local newexp = self.exp - exp --TriggerEvent('frp-logging:server:nowait:logg', self.source, 'progression', 'red', '*Speler heeft XP weggehaald!*\n**Totaal oud EXP:** ' .. self.exp .. ' [LEVEL: ' .. exports['es_extended']:getCurrentLevel(self.exp) .. ']\n**Totaal nieuw EXP:** ' .. newexp .. '[LEVEL: ' .. exports['es_extended']:getCurrentLevel(newexp) .. ']\n**Eraf gehaalde EXP:**' .. exp .. '\n**Reden:** ' .. reason) TriggerClientEvent('frp-boilerplate:client:exp:sync', self.source, newexp, self.exp) self.exp = newexp end function self.updateCoords(coords) self.coords = {x = ESX.Math.Round(coords.x, 1), y = ESX.Math.Round(coords.y, 1), z = ESX.Math.Round(coords.z, 1), heading = ESX.Math.Round(coords.heading or 0.0, 1)} end function self.getCoords(vector) if vector then return vector3(self.coords.x, self.coords.y, self.coords.z) else return self.coords end end function self.kick(reason) DropPlayer(self.source, reason) end function self.setMoney(money, reason, sender) money = ESX.Math.Round(money) self.setAccountMoney('money', money, reason, sender) end function self.getMoney() return self.getAccount('money').money end function self.addMoney(money, reason) money = ESX.Math.Round(money) self.addAccountMoney('money', money, reason) end function self.removeMoney(money, reason) money = ESX.Math.Round(money) self.removeAccountMoney('money', money, reason) end function self.getIdentifier() return self.identifier end function self.setGroup(newGroup, reason, sender) local usedReason = reason or 'Automatisch (geen reden opgegeven)' ExecuteCommand(('remove_principal identifier.%s group.%s'):format(self.identifier, self.group)) if self.group ~= 'user' then exports['frp-boilerplate']:removeStaff(self.source) end self.group = newGroup if self.group ~= 'user' then exports['frp-boilerplate']:addStaff(self.source) end local ped = GetPlayerPed(self.source) Entity(ped).state.group = newGroup ExecuteCommand(('add_principal identifier.%s group.%s'):format(self.identifier, newGroup)) end function self.getGroup() return self.group end function self.triggerEvent(eventname, ...) TriggerClientEvent(eventname, self.source, ...) end function self.set(k, v) self.variables[k] = v end function self.get(k) return self.variables[k] end function self.getAccounts(minimal) if minimal then local minimalAccounts = {} for k,v in ipairs(self.accounts) do minimalAccounts[v.name] = v.money end return minimalAccounts else return self.accounts end end function self.getAccount(account) for k,v in ipairs(self.accounts) do if v.name == account then return v end end end function self.getInventory(minimal) if minimal then local minimalInventory = {} for k, v in ipairs(self.inventory) do if v.count > 0 then minimalInventory[v.name] = v.count end end return minimalInventory end return self.inventory end function self.getJob() return self.job end function self.getJob2() return self.job2 end function self.getLoadout(minimal) if minimal then local minimalLoadout = {} for k,v in ipairs(self.loadout) do minimalLoadout[v.name] = {ammo = v.ammo} if v.tintIndex > 0 then minimalLoadout[v.name].tintIndex = v.tintIndex end if #v.components > 0 then local components = {} for k2,component in ipairs(v.components) do if component ~= 'clip_default' then components[#components + 1] = component end end if #components > 0 then minimalLoadout[v.name].components = components end end end return minimalLoadout else return self.loadout end end function self.getName() return self.name end function self.setName(newName) self.name = newName end function self.setAccountMoney(accountName, money, reason, opositeId) local usedReason = reason or 'Automatisch (geen reden opgegeven)' if money >= 0 then local account = self.getAccount(accountName) if account then local newMoney = ESX.Math.Round(money) opositeId = opositeId or 'Geen' account.money = newMoney self.triggerEvent('esx:setAccountMoney', account) end end end function self.addAccountMoney(accountName, money, reason, opositeId) local usedReason = reason or 'Automatisch (geen reden opgegeven)' if money > 0 then local account = self.getAccount(accountName) opositeId = opositeId or 'Geen' if account then local newMoney = account.money + ESX.Math.Round(money) if newMoney <= -1000000 then ESX.FlagPlayer(self.source, 'Heeft geprobeerd addAccountMoney te manipuleren (te veel schuld)', true) return end account.money = newMoney self.triggerEvent('esx:setAccountMoney', account) end end end function self.removeAccountMoney(accountName, money, reason, opositeId) local usedReason = reason or 'Automatisch (geen reden opgegeven)' if money > 0 then local account = self.getAccount(accountName) opositeId = opositeId or 'Geen' if account then local newMoney = account.money - ESX.Math.Round(money) if newMoney <= -1000000 then ESX.FlagPlayer(self.source, 'Heeft geprobeerd removeAccountMoney te manipuleren (te veel schuld)', true) return end account.money = newMoney self.triggerEvent('esx:setAccountMoney', account) end end end function self.getInventoryItem(name, metadata) for k,v in ipairs(self.inventory) do if v.name == name then return v end end end function self.addInventoryItem(name, count, metadata, slot) local item = self.getInventoryItem(name) if item then count = ESX.Math.Round(count) item.count = item.count + count self.weight = self.weight + (item.weight * count) TriggerEvent('esx:onAddInventoryItem', self.source, item.name, item.count) self.triggerEvent('esx:addInventoryItem', item.name, item.count) end end function self.removeInventoryItem(name, count, metadata, slot) local item = self.getInventoryItem(name) if item then count = ESX.Math.Round(count) local newCount = item.count - count if newCount >= 0 then item.count = newCount self.weight = self.weight - (item.weight * count) TriggerEvent('esx:onRemoveInventoryItem', self.source, item.name, item.count) self.triggerEvent('esx:removeInventoryItem', item.name, item.count) end end end function self.setInventoryItem(name, count, metadata) local item = self.getInventoryItem(name) if item and count >= 0 then count = ESX.Math.Round(count) if count > item.count then self.addInventoryItem(item.name, count - item.count) else self.removeInventoryItem(item.name, item.count - count) end end end function self.getWeight() return self.weight end function self.getMaxWeight() return self.maxWeight end function self.canCarryItem(name, count, metadata) local currentWeight, itemWeight = self.weight, ESX.Items[name].weight local newWeight = currentWeight + (itemWeight * count) return newWeight <= self.maxWeight end function self.canSwapItem(firstItem, firstItemCount, testItem, testItemCount) local firstItemObject = self.getInventoryItem(firstItem) local testItemObject = self.getInventoryItem(testItem) if firstItemObject.count >= firstItemCount then local weightWithoutFirstItem = ESX.Math.Round(self.weight - (firstItemObject.weight * firstItemCount)) local weightWithTestItem = ESX.Math.Round(weightWithoutFirstItem + (testItemObject.weight * testItemCount)) return weightWithTestItem <= self.maxWeight end return false end function self.setMaxWeight(newWeight) self.maxWeight = newWeight self.triggerEvent('esx:setMaxWeight', self.maxWeight) end -- =========[ SAFE setJob ]========= function self.setJob(job, grade, reason, opositeId) grade = tostring(grade) local usedReason = reason or 'Automatisch (geen reden opgegeven)' local lastJob = json.decode(json.encode(self.job)) if ESX.DoesJobExist(job, grade) then local jobObject, gradeObject = ESX.Jobs[job], ESX.Jobs[job].grades[grade] self.job.id = jobObject.id self.job.name = jobObject.name self.job.label = jobObject.label self.job.grade = tonumber(grade) self.job.grade_name = gradeObject.name self.job.grade_label = gradeObject.label self.job.grade_salary = gradeObject.salary self.job.skin_male = gradeObject.skin_male and json.decode(gradeObject.skin_male) or {} self.job.skin_female = gradeObject.skin_female and json.decode(gradeObject.skin_female) or {} TriggerEvent('esx:setJob', self.source, self.job, lastJob) self.triggerEvent('esx:setJob', self.job) else print(('[es_extended] [WARNING] Ongeldige .setJob() voor "%s"'):format(self.identifier)) end end -- =========[ SAFE setJob2 ]========= function self.setJob2(job2, grade2, reason, opositeId) grade2 = tostring(grade2) local usedReason = reason or 'Automatisch (geen reden opgegeven)' local lastJob = json.decode(json.encode(self.job2)) if ESX.DoesJob2Exist(job2, grade2) then local job2Object = ESX.Jobs[job2] local grade2Object = job2Object.grades[grade2] local firstName = self.get('firstname') or '' local lastName = self.get('lastname') or '' self.job2.id = job2Object.id self.job2.name = job2Object.name self.job2.label = job2Object.label self.job2.grade = tonumber(grade2) self.job2.grade_name = grade2Object.name self.job2.grade_label = grade2Object.label self.job2.grade_salary = grade2Object.salary self.job2.skin_male = grade2Object.skin_male and json.decode(grade2Object.skin_male) or {} self.job2.skin_female = grade2Object.skin_female and json.decode(grade2Object.skin_female) or {} TriggerEvent('esx:setJob2', self.source, self.job2, lastJob) self.triggerEvent('esx:setJob2', self.job2) else print(('[es_extended] [WARNING] Ongeldige .setJob2() voor "%s"'):format(self.identifier)) end end function self.hasItem(item, metadata) for k,v in ipairs(self.inventory) do if (v.name == item) and (v.count >= 1) then return v, v.count end end return false end function self.showNotification(typemsg, msg, timemsg) self.triggerEvent('frp-notifications:client:notify', typemsg, msg, timemsg) end function self.sendChatMessage(msgtype, title, text) self.triggerEvent('chatMessage', title, msgtype, text) end function self.showHelpNotification(msg, thisFrame, beep, duration) self.triggerEvent('esx:showHelpNotification', msg, thisFrame, beep, duration) end for fnName,fn in pairs(targetOverrides) do self[fnName] = fn(self) end return self end