Moderators IIYAMA Posted September 11, 2015 Moderators Share Posted September 11, 2015 Map loader This is a map loader, which can let specific players download a map of choice. Maps will be generated clientside and the resource is capable of loading extreme large maps. Loading the map will be done with a speed the pc can handle. The code execution time will be reduced to circa 10 ms. Which is the frame time of a player with 100 fps. So technically when you have 100 fps you still have 98/100 fps when this resource is loading a map. But this is based on running only this resource and based on predictions/knowledge. Which you can't trust... The .map files are unloaded afterwards reading them. But the resource will keep a buffer of the processed data until no more players are using that map. This will speed up the resource when it is used for multiply players. The resource can be managed with the following functions (serverside): loadMapForTarget() Require: element player/root, string mapName Returns: boolean success, string message unloadMapForTarget() Require: element player/root, string mapName Returns: boolean success, string message getPlayerDownloadProgress() Require: element player Returns: int percentages or boolean false Version 1.0.1 or higher getPlayerMapStatus() Require: element player, string mapName Returns: string status or boolean false Status list: string "DOWNLOADING" -- Player is downloading the map. string "LOADING" -- Player is generating/loading the map string "LOADED" -- Player has loaded the map. boolean false -- Player value is invalid or the player hasn't started downloading this map. Events(serverside): "onPlayerLoadedMap" Source: element player Parameters: string mapName int loadTime "onPlayerUnloadedMap" Source: element player Arguments: string mapName Version 1.0.1 or higher "onPlayerCancelMapDownload" Source: element player Arguments: string mapName Events(clientside): "onClientPlayerLoadedMap" Source: element localPlayer Arguments: string mapName, int loadTime "onClientPlayerUnloadedMap" Source: element localPlayer Arguments: string mapName The same information about the functions and the events can be found inside the meta.xml Element types that are supported: objects, peds, vehicles, markers and pickups If you found any bugs, which might be in there. Don't be shy and let me know, I will exterminate them. And don't forget, this resource require some rights in order to read map files from other resources: DOWNLOAD 1.0.2 For developers a quick source code preview: Server Spoiler --[[ Player data ]] local loadedPlayers = {} -- < Players that have loaded the resource local downloadStatusPlayerData = {} local mapsDownloadedBy = {} --[[ Map data ]] local mapsBuffer = {} -- < Maps are saved inside of the memory to improving the loading speed. local mapElementIndex = 1 -- < create unique identifiers local mapElements = {} -- < Table with CUSTOM serverside map elements: mapElements[mapName] = element local mapsLoadedBy = {} -- < Table with players that have loaded specific maps: mapsLoadedBy[mapName][player] = status true/nil --[[ Config ]] local validVehicleIDS = { [602] = true, [545] = true, [496] = true, [517] = true, [401] = true, [410] = true, [518] = true, [600] = true, [527] = true, [436] = true, [589] = true, [580] = true, [419] = true, [439] = true, [533] = true, [549] = true, [526] = true, [491] = true, [474] = true, [445] = true, [467] = true, [604] = true, [426] = true, [507] = true, [547] = true, [585] = true, [405] = true, [587] = true, [409] = true, [466] = true, [550] = true, [492] = true, [566] = true, [546] = true, [540] = true, [551] = true, [421] = true, [516] = true, [529] = true, [592] = true, [553] = true, [577] = true, [488] = true, [511] = true, [497] = true, [548] = true, [563] = true, [512] = true, [476] = true, [593] = true, [447] = true, [425] = true, [519] = true, [520] = true, [460] = true, [417] = true, [469] = true, [487] = true, [513] = true, [581] = true, [510] = true, [509] = true, [522] = true, [481] = true, [461] = true, [462] = true, [448] = true, [521] = true, [468] = true, [463] = true, [586] = true, [472] = true, [473] = true, [493] = true, [595] = true, [484] = true, [430] = true, [453] = true, [452] = true, [446] = true, [454] = true, [485] = true, [552] = true, [431] = true, [438] = true, [437] = true, [574] = true, [420] = true, [525] = true, [408] = true, [416] = true, [596] = true, [433] = true, [597] = true, [427] = true, [599] = true, [490] = true, [432] = true, [528] = true, [601] = true, [407] = true, [428] = true, [544] = true, [523] = true, [470] = true, [598] = true, [499] = true, [588] = true, [609] = true, [403] = true, [498] = true, [514] = true, [524] = true, [423] = true, [532] = true, [414] = true, [578] = true, [443] = true, [486] = true, [515] = true, [406] = true, [531] = true, [573] = true, [456] = true, [455] = true, [459] = true, [543] = true, [422] = true, [583] = true, [482] = true, [478] = true, [605] = true, [554] = true, [530] = true, [418] = true, [572] = true, [582] = true, [413] = true, [440] = true, [536] = true, [575] = true, [534] = true, [567] = true, [535] = true, [576] = true, [412] = true, [402] = true, [542] = true, [603] = true, [475] = true, [449] = true, [537] = true, [538] = true, [570] = true, [441] = true, [464] = true, [501] = true, [465] = true, [564] = true, [568] = true, [557] = true, [424] = true, [471] = true, [504] = true, [495] = true, [457] = true, [539] = true, [483] = true, [508] = true, [571] = true, [500] = true, [444] = true, [556] = true, [429] = true, [411] = true, [541] = true, [559] = true, [415] = true, [561] = true, [480] = true, [560] = true, [562] = true, [506] = true, [565] = true, [451] = true, [434] = true, [558] = true, [494] = true, [555] = true, [502] = true, [477] = true, [503] = true, [579] = true, [400] = true, [404] = true, [489] = true, [505] = true, [479] = true, [442] = true, [458] = true, [606] = true, [607] = true, [610] = true, [590] = true, [569] = true, [611] = true, [584] = true, [608] = true, [435] = true, [450] = true, [591] = true, [594] = true} local validPaintJobs = {[0]=true, [1]=true, [2]=true, [3]=true} local validMarkerTypes = {["checkpoint"]=true, ["ring"]=true, ["cylinder"]=true, ["arrow"]=true, ["corona"]=true} local validPedModels = {} local downloadSpeed = 1024 * 1024 if true then local validPedModelsArray = getValidPedModels() for i=1,#validPedModelsArray do validPedModels[validPedModelsArray[i]] = true end end local hex2rgb = function (hex) -- < function source: https://gist.github.com/jasonbradley/4357406 hex = hex:gsub("#", "") return tonumber("0x"..hex:sub(1, 2)), tonumber("0x"..hex:sub(3, 4)), tonumber("0x"..hex:sub(5, 6)) end function loadMapForTarget (target, mapName) if mapName ~= "" and isElement(target) and (getElementType(target) == "player" or target == root) then if target == root or downloadStatusPlayerData[target] then local mapContent = mapsBuffer[mapName] if not mapContent then local mapResource = getResourceFromName (mapName) if mapResource and getResourceInfo ( mapResource, "type" ) == "map" then local metaXmlNote = xmlLoadFile ( ":" .. mapName .. "/meta.xml" ) if metaXmlNote then mapContent = {} --[[ Support for multiple map files inside of a single resource ]] local mapNoteIndex = 0 repeat local mapNote = xmlFindChild ( metaXmlNote, "map", mapNoteIndex ) if mapNote then local mapFileName = xmlNodeGetAttribute ( mapNote, "src" ) if mapFileName then local mapNote = xmlLoadFile ( ":" .. mapName .. "/" .. mapFileName ) if mapNote then local mapNoteChildren = xmlNodeGetChildren ( mapNote) if mapNoteChildren and #mapNoteChildren > 0 then --[[ Reading the map ]] for i=1, #mapNoteChildren do local child = mapNoteChildren[i] local childName = xmlNodeGetName (child) if childName == "object" then local content = {} local model = tonumber(xmlNodeGetAttribute ( child, "model" )) local pos = {tonumber(xmlNodeGetAttribute ( child, "posX" )) or 0,tonumber(xmlNodeGetAttribute ( child, "posY")) or 0,tonumber(xmlNodeGetAttribute ( child, "posZ")) or 0} local rot = {tonumber(xmlNodeGetAttribute ( child, "rotX" )) or 0,tonumber(xmlNodeGetAttribute ( child, "rotY")) or 0,tonumber(xmlNodeGetAttribute ( child, "rotZ")) or 0} local int = tonumber(xmlNodeGetAttribute ( child, "interior")) or 0 local dim = tonumber(xmlNodeGetAttribute ( child, "dimension")) or 0 local scale = tonumber(xmlNodeGetAttribute ( child, "scale")) or 1 local col = xmlNodeGetAttribute ( child, "collisions") or "true" local alpha = tonumber(xmlNodeGetAttribute ( child, "alpha")) or 255 local frozen = xmlNodeGetAttribute ( child, "frozen") or "false" local sided = xmlNodeGetAttribute ( child, "doublesided") or "false" local breakable = xmlNodeGetAttribute ( child, "breakable") or "true" if model and pos and rot and int and dim and scale and (breakable == "true" or breakable == "false") and (col == "true" or col == "false" ) and (alpha and (alpha >= 0 or alpha <= 255)) and (frozen == "true" or frozen == "false") and (sided == "true" or sided == "false") then content["type"] = "object" content["model"] = model content["pos"] = pos content["rot"] = rot content["int"] = int content["dim"] = dim content["scale"] = scale content["col"] = col == "true" content["alpha"] = alpha content["frozen"] = frozen == "true" content["sided"] = sided == "true" content["breakable"] = breakable == "true" mapContent[#mapContent+1] = content end elseif childName == "marker" then local content = {} local pos = {tonumber(xmlNodeGetAttribute ( child, "posX" )) or 0,tonumber(xmlNodeGetAttribute ( child, "posY")) or 0,tonumber(xmlNodeGetAttribute ( child, "posZ")) or 0} local markerType = xmlNodeGetAttribute ( child, "type" ) local size = tonumber(xmlNodeGetAttribute ( child, "size")) or 4 local int = tonumber(xmlNodeGetAttribute ( child, "interior")) or 0 local dim = tonumber(xmlNodeGetAttribute ( child, "dimension")) or 0 local color = xmlNodeGetAttribute ( child,"color") local R,G,B = 0, 0, 255, 255 if color and color ~= "" then local R2, G2, B2 = hex2rgb(color) if R2 and G2 and B2 then R, G, B = R2, G2, B2 end end if pos and validMarkerTypes[markerType] and size and int and dim then content["type"] = "marker" content["pos"] = pos content["int"] = int content["dim"] = dim content["size"] = size content["markerType"] = markerType content["color"] = {R, G, B} mapContent[#mapContent + 1] = content end elseif childName == "vehicle" then local content = {} local model = tonumber(xmlNodeGetAttribute ( child, "model" )) local pos = {tonumber(xmlNodeGetAttribute ( child, "posX" )) or 0,tonumber(xmlNodeGetAttribute ( child, "posY")) or 0,tonumber(xmlNodeGetAttribute ( child, "posZ")) or 0} local rot = {tonumber(xmlNodeGetAttribute ( child, "rotX" )) or 0,tonumber(xmlNodeGetAttribute ( child, "rotY")) or 0,tonumber(xmlNodeGetAttribute ( child, "rotZ")) or 0} local plate = xmlNodeGetAttribute ( child, "plate" ) local int = tonumber(xmlNodeGetAttribute ( child,"interior")) or 0 local dim = tonumber(xmlNodeGetAttribute ( child,"dimension")) or 0 local paintjob = tonumber(xmlNodeGetAttribute ( child,"paintjob")) or 0 local color = xmlNodeGetAttribute ( child,"color") if color and color ~= "" then color = split(color,",") if color and #color == 0 then color = nil end else color = nil end local upgrades = xmlNodeGetAttribute ( child,"upgrades") if upgrades and upgrades ~= "" then upgrades = split(upgrades,",") if upgrades and #upgrades == 0 then upgrades = nil end else upgrades = nil end if validVehicleIDS[model] and pos and rot and plate and int and dim and validPaintJobs[paintjob] then content["type"] = "vehicle" content["model"] = model content["pos"] = pos content["rot"] = rot content["plate"] = tostring(plate) content["int"] = int content["dim"] = dim content["paintjob"] = paintjob if upgrades then content["upgrades"] = upgrades end if color then content["color"] = color end mapContent[#mapContent+1] = content end elseif childName == "ped" then local content = {} local model = tonumber(xmlNodeGetAttribute ( child, "model" )) local pos = {tonumber(xmlNodeGetAttribute ( child, "posX" )) or 0,tonumber(xmlNodeGetAttribute ( child, "posY")) or 0,tonumber(xmlNodeGetAttribute ( child, "posZ")) or 0} local rot = tonumber(xmlNodeGetAttribute ( child, "rotZ" )) or 0 local int = tonumber(xmlNodeGetAttribute ( child,"interior")) or 0 local dim = tonumber(xmlNodeGetAttribute ( child,"dimension")) or 0 local frozen = xmlNodeGetAttribute ( child,"frozen") or "false" local alpha = tonumber(xmlNodeGetAttribute ( child,"alpha")) or 255 if validPedModels[model] and pos and rot and int and dim and (frozen == "true" or frozen == "false") and alpha then content["type"] = "ped" content["model"] = model content["pos"] = pos content["rot"] = rot content["int"] = int content["dim"] = dim content["alpha"] = alpha content["frozen"] = frozen == "true" mapContent[#mapContent+1] = content end elseif childName == "pickup" then local content = {} local pos = {tonumber(xmlNodeGetAttribute ( child, "posX" )) or 0,tonumber(xmlNodeGetAttribute ( child, "posY")) or 0,tonumber(xmlNodeGetAttribute ( child, "posZ")) or 0} local int = tonumber(xmlNodeGetAttribute ( child,"interior")) or 0 local dim = tonumber(xmlNodeGetAttribute ( child,"dimension")) or 0 local theType = xmlNodeGetAttribute ( child,"type") local pickupType = theType == "health" and 0 or theType == "armor" and 1 or 2 if tonumber(theType) then theType = tonumber(theType) end if pos and pickupType and theType and theType ~= "" and int and dim then content["type"] = "pickup" content["pickupType"] = pickupType content["theType"] = theType content["int"] = int content["dim"] = dim content["pos"] = pos local amount = tonumber(xmlNodeGetAttribute ( child,"amount")) if amount then content["amount"] = amount end local respawn = tonumber(xmlNodeGetAttribute ( child,"respawn")) if respawn then content["respawn"] = respawn end mapContent[#mapContent + 1] = content end end end end xmlUnloadFile(mapNote) end end end mapNoteIndex = mapNoteIndex + 1 until not mapNote xmlUnloadFile (metaXmlNote) if #mapContent > 0 then mapsBuffer[mapName] = mapContent else mapContent = nil end end end end if mapContent then local mapElement = mapElements[mapName] if not mapElement then mapElement = createElement("serverMapElement", "map-index-" .. mapElementIndex) mapElementIndex = mapElementIndex + 1 mapElements[mapName] = mapElement end local playersDownloadThisMap = mapsDownloadedBy[mapName] if not playersDownloadThisMap then mapsDownloadedBy[mapName] = {} playersDownloadThisMap = mapsDownloadedBy[mapName] end if target == root then local downloadingPlayers = 0 for i=1, #loadedPlayers do local player = loadedPlayers[i] if not playersDownloadThisMap[player] then triggerLatentClientEvent(player,"onClientMapReceive",downloadSpeed,resourceRoot,mapName,mapContent,mapElement) local playerData = downloadStatusPlayerData[player] local handles = getLatentEventHandles (player) local handler = handles[#handles] playerData[#playerData+1] = handler playersDownloadThisMap[player] = handler downloadingPlayers = downloadingPlayers + 1 end end local playerCount = getPlayerCount() return true,downloadingPlayers .. "/" .. playerCount .. " loaded players are downloading and " .. #loadedPlayers-downloadingPlayers .. "/" .. playerCount .. " already have downloaded the map: " .. mapName else local player = target if not playersDownloadThisMap[player] then triggerLatentClientEvent(player,"onClientMapReceive",downloadSpeed,resourceRoot,mapName,mapContent,mapElement) local playerData = downloadStatusPlayerData[player] local handles = getLatentEventHandles (player) local handler = handles[#handles] playerData[#playerData+1] = handler playersDownloadThisMap[player] = handler return true, getPlayerName(player) .. " started downloading the map: " .. mapName else return false, getPlayerName(player) .. " has/is already downloaded/downloading this map: " .. mapName end end else return false,"No valid map/content found." end else return false,"This player can't receive maps yet. His resource hasn't been loaded." end end return false,"Incorrect arguments." end function unloadMapForTarget (target,mapName) if mapName ~= "" and isElement(target) and (getElementType(target) == "player" or target == root) then local targetingAll = target == root local destroyedForPlayer = false local usingThisMap = 0 local playersDownloadThisMap = mapsDownloadedBy[mapName] if playersDownloadThisMap then for player,handler in pairs(playersDownloadThisMap) do local playerIsElement = isElement(player) if targetingAll then if playerIsElement then local status = getLatentEventStatus(player,handler) if status and status["percentComplete"] ~= 100 then if cancelLatentEvent( player, handler ) then triggerEvent("onPlayerCancelMapDownload",player,mapName) end end end elseif player == target then if playerIsElement then local status = getLatentEventStatus(player,handler) if status and status["percentComplete"] ~= 100 then if cancelLatentEvent( player, handler ) then triggerEvent("onPlayerCancelMapDownload",player,mapName) end end end destroyedForPlayer = true playersDownloadThisMap[player] = nil else if playerIsElement then usingThisMap = usingThisMap + 1 else playersDownloadThisMap[player] = nil end end end if targetingAll or usingThisMap == 0 then mapsDownloadedBy[mapName] = nil end end local mapElement = mapElements[mapName] if mapElement then if isElement(mapElement) then if targetingAll or usingThisMap == 0 then destroyElement(mapElement) else local player = target triggerClientEvent(player,"onClientMapReceiveCancel",resourceRoot,mapElement,mapName) end end end if targetingAll or usingThisMap == 0 then mapElements[mapName] = nil local removeStatus = mapsBuffer[mapName] and true or false mapsBuffer[mapName] = nil mapsLoadedBy[mapName] = nil if removeStatus then return true, "Map buffer cleaned and destroyed for target/player." else return false, "Can't find loaded map." end end if destroyedForPlayer then return true, "Destroyed for player." end end return false end function getPlayerDownloadProgress(player) if isElement(player) then local handles = downloadStatusPlayerData[player] local activeHandles = 0 local percentCompleteTotal = 0 for i=#handles,1,-1 do local handler = handles[i] local status = getLatentEventStatus(player,handler) if status and status["percentComplete"] ~= 100 then activeHandles = activeHandles + 1 percentCompleteTotal = percentCompleteTotal + status["percentComplete"] else table.remove(handles,i) end end if activeHandles > 0 then return math.floor(percentCompleteTotal/activeHandles) else return 100 end end return false end function getPlayerMapStatus (player, mapName) if isElement(player) then local playersDownloadThisMap = mapsDownloadedBy[mapName] if playersDownloadThisMap then local handler = playersDownloadThisMap[player] if handler then local status = getLatentEventStatus(player, handler) if status and status["percentComplete"] ~= 100 then return "DOWNLOADING" else local loadedBy = mapsLoadedBy[mapName] if loadedBy and loadedBy[player] then return "LOADED" else return "LOADING" end end end end end return false end addEvent("onClientMapDownloadResourceStart",true) addEventHandler("onClientMapDownloadResourceStart",resourceRoot, function (player) if player == client and source == resourceRoot and isElement(player) then loadedPlayers[#loadedPlayers+1] = client downloadStatusPlayerData[client] = {} end end) addEventHandler("onPlayerQuit",root, function () downloadStatusPlayerData[source] = nil for i=1,#loadedPlayers do if loadedPlayers[i] == source then table.remove(loadedPlayers,i) break end end for mapName, playersThatDownloaded in pairs(mapsDownloadedBy) do if playersThatDownloaded[source] then playersThatDownloaded[source] = nil end local playerCount = 0 for player,hanler in pairs(playersThatDownloaded) do if isElement(player) then playerCount = playerCount+1 else -- < Just in case... Yet it will never be used. playersThatDownloaded[player] = nil end end if playerCount == 0 then local mapElement = mapElements[mapName] if mapElement then if isElement(mapElement) then destroyElement(mapElement) end mapElements[mapName] = nil end mapsBuffer[mapName] = nil mapsLoadedBy[mapName] = nil end end for mapName,loadedBy in pairs(mapsLoadedBy) do if loadedBy[source] then loadedBy[source] = nil end local playersLoadedThisMap = 0 for player,boolean in pairs(loadedBy) do if isElement(player) then playersLoadedThisMap = playersLoadedThisMap + 1 else loadedBy[player] = nil end end if playersLoadedThisMap == 0 then mapsLoadedBy[mapName] = nil end end end) addEvent("playerHasLoadedMap", true) addEventHandler("playerHasLoadedMap", resourceRoot, function (player, mapName, loadTime) if player == client then local loadedBy = mapsLoadedBy[mapName] if not loadedBy then mapsLoadedBy[mapName] = {} loadedBy = mapsLoadedBy[mapName] end loadedBy[player] = true triggerEvent("onPlayerLoadedMap", player, mapName, loadTime) end end) addEvent("playerHasUnloadMap", true) addEventHandler("playerHasUnloadMap", resourceRoot, function (player, mapName) if player == client then local loadedBy = mapsLoadedBy[mapName] if loadedBy then loadedBy[player] = nil local playersLoadedThisMap = 0 for player,boolean in pairs(loadedBy) do if isElement(player) then playersLoadedThisMap = playersLoadedThisMap + 1 else loadedBy[player] = nil end end if playersLoadedThisMap == 0 then mapsLoadedBy[mapName] = nil end end triggerEvent("onPlayerUnloadedMap", player, mapName) end end) Client Spoiler local loadedMaps = {} local renderMapDownloadStatus = false local renderMapDownloadFunction local renderMapDownloadContent = {} renderMapDownloadFunction = function () --[[ 10 ms delay* = 100 fps, which means that technically this script should not drop your fps lower than circa 100 fps. I hope this is true/true. ]] local loopTime = math.ceil(10/#renderMapDownloadContent) -- *10 ms delay divide by amount of maps. for mapIndex=#renderMapDownloadContent,1,-1 do local mapData = renderMapDownloadContent[mapIndex] local mapContent = mapData["mapContent"] local endLoop = false --local loops = 0 local endLoading = getTickCount()+loopTime local mapElement = mapData["mapElement"] local clientMapElement = mapData["clientMapElement"] local isMapElement repeat --loops = loops+1 local startIndex = mapData["startIndex"] isMapElement = isElement(mapElement) if startIndex > #mapContent or not isMapElement then --outputChatBox("startIndex: " .. startIndex .. ", #mapContent: " .. #mapContent) endLoop = true else local elementData = mapContent[startIndex] local elementType = elementData["type"] if elementType == "object" then local objectPos = elementData["pos"] local objectRot = elementData["rot"] local x,y,z = objectPos[1],objectPos[2],objectPos[3] local object = createObject(elementData["model"],x,y,z,objectRot[1],objectRot[2],objectRot[3],elementData["lowLOD"]) if object then setElementInterior(object,elementData["int"], x,y,z) setElementDimension (object,elementData["dim"]) setObjectScale (object,elementData["scale"]) setElementCollisionsEnabled (object,elementData["col"]) setElementAlpha(object,elementData["alpha"]) setElementFrozen(object,elementData["frozen"]) setElementDoubleSided (object,elementData["sided"]) setObjectBreakable(object,elementData["breakable"]) setElementParent(object,clientMapElement) end elseif elementType == "marker" then local markerPos = elementData["pos"] local color = elementData["color"] local marker = createMarker ( markerPos[1], markerPos[2], markerPos[3], elementData["markerType"],elementData["size"],color[1],color[2],color[3]) if marker then setElementInterior(marker,elementData["int"]) setElementDimension(marker,elementData["dim"]) setElementParent(marker,clientMapElement) end elseif elementType == "vehicle" then local vehiclePos = elementData["pos"] local vehicleRot = elementData["rot"] local vehicle = createVehicle (elementData["model"], vehiclePos[1],vehiclePos[2],vehiclePos[3],vehicleRot[1],vehicleRot[2],vehicleRot[3],elementData["plate"] ) if vehicle then local upgrades = elementData["upgrades"] if upgrades then for i=1,#upgrades do addVehicleUpgrade ( vehicle, upgrades[i]) end end setVehicleColor (vehicle,unpack(elementData["color"] or {0,0,0,0,0,0,0,0,0,0,0,0})) -- Set colors of vehicle clientside directly after creation doesn't work, BUG for now****. setElementParent(vehicle,clientMapElement) end elseif elementType == "ped" then local markerPos = elementData["pos"] local ped = createPed(elementData["model"],markerPos[1], markerPos[2], markerPos[3],elementData["rot"]) if ped then setElementInterior(ped,elementData["int"]) setElementFrozen(ped,elementData["frozen"]) setElementDimension(ped,elementData["dim"]) setElementAlpha(ped,elementData["alpha"]) setElementParent(ped,clientMapElement) end elseif elementType == "pickup" then local pickupPos = elementData["pos"] local pickup if elementData["respawn"] then if elementData["amount"] then pickup = createPickup(pickupPos[1],pickupPos[2],pickupPos[3],elementData["pickupType"],elementData["theType"],elementData["respawn"],elementData["amount"]) else pickup = createPickup(pickupPos[1],pickupPos[2],pickupPos[3],elementData["pickupType"],elementData["theType"],elementData["respawn"]) end else pickup = createPickup(pickupPos[1],pickupPos[2],pickupPos[3],elementData["pickupType"],elementData["theType"]) end if pickup then setElementDimension(pickup,elementData["dim"]) setElementInterior(pickup,elementData["int"]) setElementParent(pickup,clientMapElement) end end mapData["startIndex"] = startIndex+1 end --outputChatBox(tostring(getTickCount() > endLoading) .. " " .. tostring(endLoop)) until (getTickCount() > endLoading or endLoop) --outputChatBox("loops: " .. loops .. ", elements: " .. #mapContent .. ", startIndex: " .. mapData["startIndex"]) if endLoop then if isMapElement then local mapName = mapData["mapName"] loadedMaps[mapName] = true local loadTime = getTickCount()-mapData["startLoadingTime"] triggerEvent("onClientPlayerLoadedMap",localPlayer,mapName,loadTime) triggerServerEvent("playerHasLoadedMap",resourceRoot,localPlayer,mapName,loadTime) end table.remove(renderMapDownloadContent,mapIndex) end end if #renderMapDownloadContent == 0 then removeEventHandler("onClientPreRender",root,renderMapDownloadFunction) end end addEvent("onClientMapReceiveCancel",true) addEventHandler("onClientMapReceiveCancel",resourceRoot, function (mapElement,mapName) for i=1,#renderMapDownloadContent do local mapData = renderMapDownloadContent[i] if mapData and mapData["mapName"] == mapName then table.remove(renderMapDownloadContent,i) break end end if isElement(mapElement) then local clientMapElement = getElementChild (mapElement, 0 ) if clientMapElement then destroyElement(clientMapElement) end end if loadedMaps[mapName] then triggerEvent("onClientPlayerUnloadedMap",localPlayer,mapName) triggerServerEvent("playerHasUnloadMap",resourceRoot,localPlayer,mapName) loadedMaps[mapName] = nil end end) addEvent("onClientMapReceive",true) addEventHandler("onClientMapReceive",resourceRoot, function (mapName,mapContent,mapElement) if type(mapContent) == "table" and source == resourceRoot then local previousClientMapElement = getElementChild (mapElement, 0 ) if previousClientMapElement then outputDebugString("ERROR: Map_loader, something went wrong clientside! Fixing it now.") destroyElement(previousClientMapElement) end local clientMapElement = createElement("clientMapElement") if clientMapElement then setElementParent(clientMapElement,mapElement) renderMapDownloadContent[#renderMapDownloadContent+1] = {["mapName"]=mapName,["clientMapElement"]=clientMapElement,["startLoadingTime"]=getTickCount(),["mapContent"]=mapContent,["startIndex"]=1,["mapElement"]=mapElement} if not renderMapDownloadStatus then addEventHandler("onClientPreRender",root,renderMapDownloadFunction,true,"high+5") end end end end) addEventHandler("onClientResourceStart",resourceRoot, function () triggerServerEvent("onClientMapDownloadResourceStart",resourceRoot,localPlayer) end) -- the structure -- --[[ { {-- object ["model"]=1, ["pos"]={x,y,z}, ["rot"]={xr,yr,zr}, ["lowLOD"]=false, ["int"]=1, ["dim"]=1, ["scale"]=1, ["col"]=true, ["alpha"]=255, ["frozen"]=false }, ]] 1 Link to comment
JR10 Posted September 11, 2015 Share Posted September 11, 2015 Why is it compiled? If it is a framework then it shouldn't be compiled. Link to comment
Moderators IIYAMA Posted September 11, 2015 Author Moderators Share Posted September 11, 2015 Hmm there you got a point, away with that word. Link to comment
Moderators IIYAMA Posted September 12, 2015 Author Moderators Share Posted September 12, 2015 Another function will be implemented soon: (it is already finished, but for next version 1.0.1) [b]getPlayerMapStatus()[/b] Require: [i][color=#00FF00]element [/color]player, [color=#00FF00]string [/color]mapName[/i] Returns: [i][color=#00FF00]string [/color]status[/i] Or [i][color=#00FF00]boolean [/color]false[/i] Possible status: "DOWNLOADING" [color=#00FF00]-- Player is downloading the map.[/color] "LOADING" [color=#00FF00]-- Player is generating/loading the map[/color] "LOADED" [color=#00FF00] -- Player has loaded the map.[/color] false [color=#00FF00]-- Player variable is invalid or the player hasn't started downloading this map.[/color] And a new event: [color=#0000FF]"onPlayerCancelMapDownload"[/color] Source: [i][color=#00FF00]element [/color]player Arguments: [color=#00FF00]string [/color]mapName[/i] RELEASED 1.0.1 Link to comment
Gravestone Posted March 22, 2016 Share Posted March 22, 2016 Where the hell do I need to add my map name and target player name? Link to comment
Malak Posted March 22, 2016 Share Posted March 22, 2016 Where the hell do I need to add my map name and target player name? Hm let me see, all gamemode without execute mapmanager ^^ Anyway its really good script, good job ! Link to comment
Moderators IIYAMA Posted March 22, 2016 Author Moderators Share Posted March 22, 2016 Where the hell do I need to add my map name and target player name? local target = getPlayerFromName("myName") if target then exports["map_loader"]:loadMapForTarget(target, "sth-jackson") end This map loader is for scripters, there is no CLI(command line interface) or GUI because it is irrelevant for the target user. Link to comment
Gravestone Posted March 23, 2016 Share Posted March 23, 2016 Oh I see. We need to write this code in .lua file located in our map folder? And what if I want the map to be for everyone? Link to comment
Moderators IIYAMA Posted March 23, 2016 Author Moderators Share Posted March 23, 2016 That .lua file is only for controlling the map_loader resource, it can be merged with any kind of resource. From there it can load every map you want. And what if I want the map to be for everyone? exports["map_loader"]:loadMapForTarget(root, "sth-jackson") Read the instructions at the top carefully. Link to comment
Moderators IIYAMA Posted May 24, 2020 Author Moderators Share Posted May 24, 2020 I have uploaded an uncompiled version. Because compiled scripts are not healthy for developers. 1 Link to comment
enesbayrktar Posted February 2, 2021 Share Posted February 2, 2021 İ have one question about that script usage. For example i have one .map file, how can i execute .map file with this resource? can you give a example? exports["map_loader"]:loadMapForTarget(root, "sth-jackson") -- sth-jackson is .map file name or script name? @IIYAMA Link to comment
Moderators IIYAMA Posted February 2, 2021 Author Moderators Share Posted February 2, 2021 (edited) 31 minutes ago, enesbayrktar said: script name? 1. It is the resourceName. (the folder that contains the meta.xml, that is the name that should be used) As you can see here: "sth-jackson" https://community.multitheftauto.com/index.php?p=resources&s=details&id=527 2. The script will detect all map files inside of the meta.xml and combine those. 3. As far as I can remember the resource must be unzipped. Edited February 2, 2021 by IIYAMA Link to comment
Moderators IIYAMA Posted February 5, 2021 Author Moderators Share Posted February 5, 2021 On 02/02/2021 at 23:57, enesbayrktar said: İ have one question about that script usage. For example i have one .map file, how can i execute .map file with this resource? can you give a example? exports["map_loader"]:loadMapForTarget(root, "sth-jackson") -- sth-jackson is .map file name or script name? @IIYAMA Did you got it to work? Link to comment
enesbayrktar Posted February 5, 2021 Share Posted February 5, 2021 33 minutes ago, IIYAMA said: Did you got it to work? Yeap, its worked. 1 Link to comment
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now