Files
red-valley/cache/files/mapmanager/resource.rpf

225 lines
14 KiB
Plaintext
Raw Normal View History

2026-03-29 21:41:17 +03:00
RPF2<00><00><00>k k ' ( /fxmanifest.luamapmanager_client.luamapmanager_shared.lua
-- Altering or recreating for local use only is strongly discouraged.
version '1.0.0'
author 'Cfx.re <root@cfx.re>'
description 'A flexible handler for game type/map association.'
repository 'https://github.com/citizenfx/cfx-server-data'
client_scripts {
"mapmanager_shared.lua",
"mapmanager_client.lua"
}
server_scripts {
"mapmanager_shared.lua",
"mapmanager_server.lua"
}
fx_version 'adamant'
games { 'gta5', 'rdr3' }
server_export "getCurrentGameType"
server_export "getCurrentMap"
server_export "changeGameType"
server_export "changeMap"
server_export "doesMapSupportGameType"
server_export "getMaps"
server_export "roundEnded"
rdr3_warning 'I acknowledge that this is a prerelease build of RedM, and I am aware my resources *will* become incompatible once RedM ships.'
local maps = {}
local gametypes = {}
AddEventHandler('onClientResourceStart', function(res)
-- parse metadata for this resource
-- map files
local num = GetNumResourceMetadata(res, 'map')
if num > 0 then
for i = 0, num-1 do
local file = GetResourceMetadata(res, 'map', i)
if file then
addMap(file, res)
end
end
end
-- resource type data
local type = GetResourceMetadata(res, 'resource_type', 0)
if type then
local extraData = GetResourceMetadata(res, 'resource_type_extra', 0)
if extraData then
extraData = json.decode(extraData)
else
extraData = {}
end
if type == 'map' then
maps[res] = extraData
elseif type == 'gametype' then
gametypes[res] = extraData
end
end
-- handle starting
loadMap(res)
-- defer this to the next game tick to work around a lack of dependencies
Citizen.CreateThread(function()
Citizen.Wait(15)
if maps[res] then
TriggerEvent('onClientMapStart', res)
elseif gametypes[res] then
TriggerEvent('onClientGameTypeStart', res)
end
end)
end)
AddEventHandler('onResourceStop', function(res)
if maps[res] then
TriggerEvent('onClientMapStop', res)
elseif gametypes[res] then
TriggerEvent('onClientGameTypeStop', res)
end
unloadMap(res)
end)
AddEventHandler('getMapDirectives', function(add)
if not CreateScriptVehicleGenerator then
return
end
add('vehicle_generator', function(state, name)
return function(opts)
local x, y, z, heading
local color1, color2
if opts.x then
x = opts.x
y = opts.y
z = opts.z
else
x = opts[1]
y = opts[2]
z = opts[3]
end
heading = opts.heading or 1.0
color1 = opts.color1 or -1
color2 = opts.color2 or -1
CreateThread(function()
local hash = GetHashKey(name)
RequestModel(hash)
while not HasModelLoaded(hash) do
Wait(0)
end
local carGen = CreateScriptVehicleGenerator(x, y, z, heading, 5.0, 3.0, hash, color1, color2, -1, -1, true, false, false, true, true, -1)
SetScriptVehicleGenerator(carGen, true)
SetAllVehicleGeneratorsActive(true)
state.add('cargen', carGen)
end)
end
end, function(state, arg)
Citizen.Trace("deleting car gen " .. tostring(state.cargen) .. "\n")
DeleteScriptVehicleGenerator(state.cargen)
end)
end)
-- shared logic file for map manager - don't call any subsystem-specific functions here
mapFiles = {}
function addMap(file, owningResource)
if not mapFiles[owningResource] then
mapFiles[owningResource] = {}
end
table.insert(mapFiles[owningResource], file)
end
undoCallbacks = {}
function loadMap(res)
if mapFiles[res] then
for _, file in ipairs(mapFiles[res]) do
parseMap(file, res)
end
end
end
function unloadMap(res)
if undoCallbacks[res] then
for _, cb in ipairs(undoCallbacks[res]) do
cb()
end
undoCallbacks[res] = nil
mapFiles[res] = nil
end
end
function parseMap(file, owningResource)
if not undoCallbacks[owningResource] then
undoCallbacks[owningResource] = {}
end
local env = {
math = math, pairs = pairs, ipairs = ipairs, next = next, tonumber = tonumber, tostring = tostring,
type = type, table = table, string = string, _G = env,
vector3 = vector3, quat = quat, vec = vec, vector2 = vector2
}
TriggerEvent('getMapDirectives', function(key, cb, undocb)
env[key] = function(...)
local state = {}
state.add = function(k, v)
state[k] = v
end
local result = cb(state, ...)
local args = table.pack(...)
table.insert(undoCallbacks[owningResource], function()
undocb(state)
end)
return result
end
end)
local mt = {
__index = function(t, k)
if rawget(t, k) ~= nil then return rawget(t, k) end
-- as we're not going to return nothing here (to allow unknown directives to be ignored)
local f = function()
return f
end
return function() return f end
end
}
setmetatable(env, mt)
local fileData = LoadResourceFile(owningResource, file)
local mapFunction, err = load(fileData, file, 't', env)
if not mapFunction then
Citizen.Trace("Couldn't load map " .. file .. ": " .. err .. " (type of fileData: " .. type(fileData) .. ")\n")
return
end
mapFunction()
end