Replace whole "client.lua" with this one:
--- -- Main client file with drawing and calculating. -- -- @author driver2 -- @copyright 2009-2010 driver2 -- -- Recent changes: -- 2010-02-09: Made GUI-key a setting in defaultSettings.lua, added help to radio buttons, replaced "infocenter" with "gamecenter" ------------------------- -- Initialize Settings -- ------------------------- local gamecenterResource = false settingsObject = Settings:new(defaultSettings,"settings.xml") local function s(setting,settingType) return settingsObject:get(setting,settingType) end ----------------------------- -- Variables and Constants -- ----------------------------- fonts = {"default","default-bold","clear","arial","sans","pricedown","bankgothic","diploma","beckett"} local screenWidth,screenHeight = guiGetScreenSize() local x = nil local y = nil local x2 = nil local y2 = nil local h = nil local readyToDraw = false local mapLoaded = false local screenFadedOut = false local updateIntervall = 1000 local g_CheckpointDistance = {} local g_CheckpointDistanceSum = {} local g_players = {} local g_TotalDistance = 0 local g_recordedDistances = {} local g_recordedDistancesForReplay = {} local g_times = {} ------------ -- Events -- ------------ function initiate() settingsObject:loadFromXml() mapStarted() sendMessageToServer("loaded") end addEventHandler("onClientResourceStart",getResourceRootElement(getThisResource()),initiate) function mapStarted() -- Start under the assumption that no checkpoints are found, -- so not ready to draw (also the new data hasn't been loaded -- yet) readyToDraw = false mapLoaded = false if loadMap() then -- If data was successfully loaded, prepare drawing mapLoaded = true calculateCheckpointDistance() prepareDraw() end g_times = {} g_delay = {} -- TODO: load distances for map g_recordedDistancesForReplay = g_recordedDistances g_recordedDistances = {} g_replayCount = 0 end addEventHandler("onClientMapStarting",getRootElement(),mapStarted) ------------------------------- -- Load and prepare map data -- ------------------------------- function loadMap() --local res = call(getResourceFromName("mapmanager"),"getRunningGamemodeMap") -- Get the data or empty tables, if none of these elements exist g_Spawnpoints = getAll("spawnpoint") g_Checkpoints = getAll("checkpoint") if #g_Spawnpoints > 0 and #g_Checkpoints > 0 then return true end return false end function getAll(name) local result = {} for i,element in ipairs(getElementsByType(name)) do result[i] = {} result[i].id = getElementID(element) or i local position = { tonumber(getElementData(element,"posX")), tonumber(getElementData(element,"posY")), tonumber(getElementData(element,"posZ")) } result[i].position = position; end return result end function calculateCheckpointDistance() local total = 0 local cps = {} local cpsSum = {} local pos = g_Spawnpoints[1].position local prevX, prevY, prevZ = pos[1],pos[2],pos[3] for k,v in ipairs(g_Checkpoints) do local pos = v.position if prevX ~= nil then local distance = getDistanceBetweenPoints3D(pos[1],pos[2],pos[3],prevX,prevY,prevZ) total = total + distance cps[k] = distance cpsSum[k] = total end prevX = pos[1] prevY = pos[2] prevZ = pos[3] end g_CheckpointDistance = cps g_CheckpointDistanceSum = cpsSum g_TotalDistance = total end ----------- -- Times -- ----------- -- SHOULD BE DONE: maybe reset data if player rejoins? maybe check if he already passed that checkpoint --[[ -- Adds the given time for the player at that checkpoint to the table, -- as well as displays it, if there is a time at the same checkpoint -- to compare it with. -- -- @param player player: The player element -- @param int checkpoint: The checkpoint number -- @param int time: The number of milliseconds -- @return boolean false if parameters are invalid -- ]] function addTime(player,checkpoint,time) if player == nil then return false end if g_times[player] == nil then g_times[player] = {} end g_times[player][checkpoint] = time if player == getLocalPlayer() then -- For players who passed the checkpoint you hit before you for k,v in ipairs(getElementsByType("player")) do local prevTime = getTime(v,checkpoint) --var_dump("prevTime",prevTime) if prevTime then local diff = time - prevTime g_delay[v] = {diff,getTickCount()} end end else -- For players who hit a checkpoint you already passed local prevTime = getTime(getLocalPlayer(),checkpoint) if prevTime then local diff = -(time - prevTime) g_delay[player] = {diff,getTickCount()} end end end --[[ -- Gets the time of a player for a certain checkpoint, if it exists -- and the player has already reached it (as far as race is concerned) -- -- @param player player: The player element -- @param int checkpoint: The checkpoint number -- @return mixed The number of milliseconds passed for this player -- at this checkpoint, or false if it doesn't exist -- ]] function getTime(player,checkpoint) -- Check if the desired time exists if g_times[player] ~= nil and g_times[player][checkpoint] ~= nil then -- Check if player has already reached that checkpoint. This prevents -- two scenarios from causing wrong times to appear: -- 1. When a player is set back to a previous checkpoint when he dies twice -- 2. When a player rejoins and the player element remains the same (with the times still being saved -- at the other clients) local playerHeadingForCp = getElementData(player,"race.checkpoint") if type(playerHeadingForCp) == "number" and playerHeadingForCp > checkpoint then return g_times[player][checkpoint] end end return false end --[[ -- Calculates minutes and seconds from milliseconds -- and formats the output in the form xx:xx.xx -- -- Also supports negative numbers, to which it will add a minus-sign (-) -- before the output, a plus-sign (+) otherwise. -- -- @param int milliseconds: The number of milliseconds you wish to format -- @return string The formated string or an empty string if no parameter was specified -- ]] function formatTime(milliseconds) if milliseconds == nil then return "" end local prefix = "+" if milliseconds < 0 then prefix = "-" milliseconds = -(milliseconds) end local minutes = math.floor(milliseconds / 1000 / 60) local milliseconds = milliseconds % (1000 * 60) local seconds = math.floor(milliseconds / 1000) local milliseconds = milliseconds % 1000 return string.format(prefix.."%i:%02i.%03i",minutes,seconds,milliseconds) end ------------------- -- Communication -- ------------------- function serverMessage(message,parameter) if message == "update" then addTime(parameter[1],parameter[2],parameter[3]) end if message == "times" then g_times = parameter end end addEvent("onClientRaceProgressServerMessage",true) addEventHandler("onClientRaceProgressServerMessage",getRootElement(),serverMessage) function sendMessageToServer(message,parameter) triggerServerEvent("onRaceProgressClientMessage",getRootElement(),message,parameter) end