From 53fc373f5d67491b7ce7156452c6d9593a16f361 Mon Sep 17 00:00:00 2001 From: moscovium Date: Sun, 25 Mar 2018 14:56:08 +0200 Subject: [PATCH] mapmanager: fixes and some cleanup --- .../[managers]/mapmanager/__resource.lua | 9 +- .../mapmanager/mapmanager_client.lua | 130 +++--------------- .../mapmanager/mapmanager_server.lua | 45 +++--- .../mapmanager/mapmanager_shared.lua | 85 ++++++++++++ 4 files changed, 130 insertions(+), 139 deletions(-) diff --git a/resources/[managers]/mapmanager/__resource.lua b/resources/[managers]/mapmanager/__resource.lua index 8521772..922c93c 100644 --- a/resources/[managers]/mapmanager/__resource.lua +++ b/resources/[managers]/mapmanager/__resource.lua @@ -1,11 +1,11 @@ client_scripts { - "mapmanager_client.lua", - "mapmanager_shared.lua" + "mapmanager_shared.lua", + "mapmanager_client.lua" } server_scripts { - "mapmanager_server.lua", - "mapmanager_shared.lua" + "mapmanager_shared.lua", + "mapmanager_server.lua" } resource_manifest_version "77731fab-63ca-442c-a67b-abc70f28dfa5" @@ -16,3 +16,4 @@ server_export "changeGameType" server_export "changeMap" server_export "doesMapSupportGameType" server_export "getMaps" +server_export "roundEnded" \ No newline at end of file diff --git a/resources/[managers]/mapmanager/mapmanager_client.lua b/resources/[managers]/mapmanager/mapmanager_client.lua index 3995167..c3b3e5c 100644 --- a/resources/[managers]/mapmanager/mapmanager_client.lua +++ b/resources/[managers]/mapmanager/mapmanager_client.lua @@ -1,35 +1,5 @@ -maps = {} -gametypes = {} - -AddEventHandler('getResourceInitFuncs', function(isPreParse, add) - if not isPreParse then - add('map', function(file) - addMap(file, GetInvokingResource()) - end) - - add('resource_type', function(type) - return function(params) - local resourceName = GetInvokingResource() - - if type == 'map' then - maps[resourceName] = params - elseif type == 'gametype' then - gametypes[resourceName] = params - end - end - end) - end -end) - -mapFiles = {} - -function addMap(file, owningResource) - if not mapFiles[owningResource] then - mapFiles[owningResource] = {} - end - - table.insert(mapFiles[owningResource], file) -end +local maps = {} +local gametypes = {} AddEventHandler('onClientResourceStart', function(res) -- parse metadata for this resource @@ -37,7 +7,7 @@ AddEventHandler('onClientResourceStart', function(res) -- map files local num = GetNumResourceMetadata(res, 'map') - if num then + if num > 0 then for i = 0, num-1 do local file = GetResourceMetadata(res, 'map', i) @@ -51,8 +21,6 @@ AddEventHandler('onClientResourceStart', function(res) local type = GetResourceMetadata(res, 'resource_type', 0) if type then - Citizen.Trace("type " .. res .. " " .. type .. "\n") - local extraData = GetResourceMetadata(res, 'resource_type_extra', 0) if extraData then @@ -68,12 +36,10 @@ AddEventHandler('onClientResourceStart', function(res) end end + print('map? ', res) + -- handle starting - if mapFiles[res] then - for _, file in ipairs(mapFiles[res]) do - parseMap(file, res) - end - end + loadMap(res) -- defer this to the next game tick to work around a lack of dependencies Citizen.CreateThread(function() @@ -94,73 +60,9 @@ AddEventHandler('onResourceStop', function(res) TriggerEvent('onClientGameTypeStop', res) end - if undoCallbacks[res] then - for _, cb in ipairs(undoCallbacks[res]) do - cb() - end - - undoCallbacks[res] = nil - mapFiles[res] = nil - end + unloadMap(res) end) -undoCallbacks = {} - -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 - } - - 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 - AddEventHandler('getMapDirectives', function(add) add('vehicle_generator', function(state, name) return function(opts) @@ -181,16 +83,20 @@ AddEventHandler('getMapDirectives', function(add) color1 = opts.color1 or -1 color2 = opts.color2 or -1 - local hash = GetHashKey(name) - RequestModel(hash) + CreateThread(function() + local hash = GetHashKey(name) + RequestModel(hash) - LoadAllObjectsNow() + 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) + 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) + state.add('cargen', carGen) + end) end end, function(state, arg) Citizen.Trace("deleting car gen " .. tostring(state.cargen) .. "\n") diff --git a/resources/[managers]/mapmanager/mapmanager_server.lua b/resources/[managers]/mapmanager/mapmanager_server.lua index b3b238b..cd0f418 100644 --- a/resources/[managers]/mapmanager/mapmanager_server.lua +++ b/resources/[managers]/mapmanager/mapmanager_server.lua @@ -1,25 +1,7 @@ -- loosely based on MTA's https://code.google.com/p/mtasa-resources/source/browse/trunk/%5Bmanagers%5D/mapmanager/mapmanager_main.lua -maps = {} -gametypes = {} - -AddEventHandler('getResourceInitFuncs', function(isPreParse, add) - add('resource_type', function(type) - return function(params) - local resourceName = GetInvokingResource() - - if type == 'map' then - maps[resourceName] = params - elseif type == 'gametype' then - gametypes[resourceName] = params - end - end - end) - - add('map', function(file) - AddAuxFile(file) - end) -end) +local maps = {} +local gametypes = {} local function refreshResources() local numResources = GetNumResources() @@ -47,8 +29,16 @@ end) refreshResources() AddEventHandler('onResourceStarting', function(resource) - if GetNumResourceMetadata(resource, 'map') then - -- todo: add file + local num = GetNumResourceMetadata(resource, 'map') + + if num then + for i = 0, num-1 do + local file = GetResourceMetadata(resource, 'map', i) + + if file then + addMap(file, resource) + end + end end if maps[resource] then @@ -132,7 +122,6 @@ AddEventHandler('onResourceStart', function(resource) SetGameType(gtName) print('Started gametype ' .. gtName) - TriggerClientEvent('onClientGameTypeStart', -1, getCurrentGameType()) SetTimeout(50, function() if not currentMap then @@ -155,6 +144,9 @@ AddEventHandler('onResourceStart', function(resource) end end end + + -- handle starting + loadMap(resource) end) local function handleRoundEnd() @@ -177,6 +169,10 @@ AddEventHandler('mapmanager:roundEnded', function() SetTimeout(50, handleRoundEnd) -- not a closure as to work around some issue in neolua? end) +function roundEnded() + SetTimeout(50, handleRoundEnd) +end + AddEventHandler('onResourceStop', function(resource) if resource == currentGameType then TriggerEvent('onGameTypeStop', resource) @@ -191,6 +187,9 @@ AddEventHandler('onResourceStop', function(resource) currentMap = nil end + + -- unload the map + unloadMap(resource) end) AddEventHandler('rconCommand', function(commandName, args) diff --git a/resources/[managers]/mapmanager/mapmanager_shared.lua b/resources/[managers]/mapmanager/mapmanager_shared.lua index 7d5f180..5b4f608 100644 --- a/resources/[managers]/mapmanager/mapmanager_shared.lua +++ b/resources/[managers]/mapmanager/mapmanager_shared.lua @@ -1 +1,86 @@ -- 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 + } + + 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 \ No newline at end of file