mirror of
https://github.com/citizenfx/cfx-server-data.git
synced 2025-01-10 15:43:00 +08:00
274 lines
7.2 KiB
Lua
274 lines
7.2 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)
|
||
|
|
||
|
AddEventHandler('onResourceStarting', function(resource)
|
||
|
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
|
||
|
SetMapName(maps[resource].name)
|
||
|
else
|
||
|
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 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
|