1
0
mirror of https://github.com/citizenfx/cfx-server-data.git synced 2025-01-11 00:03:18 +08:00
cfx-server-data/resources/[managers]/mapmanager/mapmanager_server.lua
2017-06-08 19:59:50 -05:00

309 lines
8.1 KiB
Lua

-- 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 function refreshResources()
local numResources = GetNumResources()
for i = 0, numResources - 1 do
local resource = GetResourceByFindIndex(i)
if GetNumResourceMetadata(resource, 'resource_type') > 0 then
local type = GetResourceMetadata(resource, 'resource_type', 0)
local params = json.decode(GetResourceMetadata(resource, 'resource_type_extra', 0))
if type == 'map' then
maps[resource] = params
elseif type == 'gametype' then
gametypes[resource] = params
end
end
end
end
AddEventHandler('onResourceListRefresh', function()
refreshResources()
end)
refreshResources()
AddEventHandler('onResourceStarting', function(resource)
if GetNumResourceMetadata(resource, 'map') then
-- todo: add file
end
if maps[resource] then
if getCurrentMap() and getCurrentMap() ~= resource then
if doesMapSupportGameType(getCurrentGameType(), resource) then
print("Changing map from " .. getCurrentMap() .. " to " .. resource)
changeMap(resource)
else
-- check if there's only one possible game type for the map
local map = maps[resource]
local count = 0
local gt
for type, flag in pairs(map.gameTypes) do
if flag then
count = count + 1
gt = type
end
end
if count == 1 then
print("Changing map from " .. getCurrentMap() .. " to " .. resource .. " (gt " .. gt .. ")")
changeGameType(gt)
changeMap(resource)
end
end
CancelEvent()
end
elseif gametypes[resource] then
if getCurrentGameType() and getCurrentGameType() ~= resource then
print("Changing gametype from " .. getCurrentGameType() .. " to " .. resource)
changeGameType(resource)
CancelEvent()
end
end
end)
math.randomseed(GetInstanceId())
local currentGameType = nil
local currentMap = nil
AddEventHandler('onResourceStart', function(resource)
if maps[resource] then
if not getCurrentGameType() then
for gt, _ in pairs(maps[resource].gameTypes) do
changeGameType(gt)
break
end
end
if getCurrentGameType() and not getCurrentMap() then
if doesMapSupportGameType(currentGameType, resource) then
if TriggerEvent('onMapStart', resource, maps[resource]) then
if maps[resource].name then
print('Started map ' .. maps[resource].name)
SetMapName(maps[resource].name)
else
print('Started map ' .. resource)
SetMapName(resource)
end
currentMap = resource
else
currentMap = nil
end
end
end
elseif gametypes[resource] then
if not getCurrentGameType() then
if TriggerEvent('onGameTypeStart', resource, gametypes[resource]) then
currentGameType = resource
local gtName = gametypes[resource].name or resource
SetGameType(gtName)
print('Started gametype ' .. gtName)
TriggerClientEvent('onClientGameTypeStart', -1, getCurrentGameType())
SetTimeout(50, function()
if not currentMap then
local possibleMaps = {}
for map, data in pairs(maps) do
if data.gameTypes[currentGameType] then
table.insert(possibleMaps, map)
end
end
if #possibleMaps > 0 then
local rnd = math.random(#possibleMaps)
changeMap(possibleMaps[rnd])
end
end
end)
else
currentGameType = nil
end
end
end
end)
local function handleRoundEnd()
local possibleMaps = {}
for map, data in pairs(maps) do
if data.gameTypes[currentGameType] then
table.insert(possibleMaps, map)
end
end
if #possibleMaps > 0 then
local rnd = math.random(#possibleMaps)
changeMap(possibleMaps[rnd])
end
end
AddEventHandler('mapmanager:roundEnded', function()
-- set a timeout as we don't want to return to a dead environment
SetTimeout(50, handleRoundEnd) -- not a closure as to work around some issue in neolua?
end)
AddEventHandler('onResourceStop', function(resource)
if resource == currentGameType then
TriggerEvent('onGameTypeStop', resource)
currentGameType = nil
if currentMap then
StopResource(currentMap)
end
elseif resource == currentMap then
TriggerEvent('onMapStop', resource)
currentMap = nil
end
end)
AddEventHandler('rconCommand', function(commandName, args)
if commandName == 'map' then
if #args ~= 1 then
RconPrint("usage: map [mapname]\n")
end
if not maps[args[1]] then
RconPrint('no such map ' .. args[1] .. "\n")
CancelEvent()
return
end
if currentGameType == nil or not doesMapSupportGameType(currentGameType, args[1]) then
local map = maps[args[1]]
local count = 0
local gt
for type, flag in pairs(map.gameTypes) do
if flag then
count = count + 1
gt = type
end
end
if count == 1 then
print("Changing map from " .. getCurrentMap() .. " to " .. args[1] .. " (gt " .. gt .. ")")
changeGameType(gt)
changeMap(args[1])
RconPrint('map ' .. args[1] .. "\n")
else
RconPrint('map ' .. args[1] .. ' does not support ' .. currentGameType .. "\n")
end
CancelEvent()
return
end
changeMap(args[1])
RconPrint('map ' .. args[1] .. "\n")
CancelEvent()
elseif commandName == 'gametype' then
if #args ~= 1 then
RconPrint("usage: gametype [name]\n")
end
if not gametypes[args[1]] then
RconPrint('no such gametype ' .. args[1] .. "\n")
CancelEvent()
return
end
changeGameType(args[1])
RconPrint('gametype ' .. args[1] .. "\n")
CancelEvent()
end
end)
function getCurrentGameType()
return currentGameType
end
function getCurrentMap()
return currentMap
end
function getMaps()
return maps
end
function changeGameType(gameType)
if currentMap and not doesMapSupportGameType(gameType, currentMap) then
StopResource(currentMap)
end
if currentGameType then
StopResource(currentGameType)
end
StartResource(gameType)
end
function changeMap(map)
if currentMap then
StopResource(currentMap)
end
StartResource(map)
end
function doesMapSupportGameType(gameType, map)
if not gametypes[gameType] then
return false
end
if not maps[map] then
return false
end
if not maps[map].gameTypes then
return true
end
return maps[map].gameTypes[gameType]
end