Jump to content

Can't get a timer to start for a mod.


Recommended Posts

Hello, i am trying to make a simple rally stage mod where you create 2 markers, one for start and one for finish, that part is good, but i am trying to make a timer start when you pass the start marker and stop counting when you pass the finish marker, then it should print the time in chat.

I started lua scripting today and used a bit of GPT just because all i knew was Java, so basically when i pass the start marker the Stage Started message doesn't show up, so i guess i am not getting the player position correctly maybe? not sure.

The only code not inserted here are 3 functions to create the start, the finish and to clear all markers, so i guess is not needed.

function checkStageProgress(player)
    if not startMarker or not finishMarker then
        return
    end
    
    local startX, startY, startZ = getElementPosition(startMarker)
    local finishX, finishY, finishZ = getElementPosition(finishMarker)
    local playerX, playerY, playerZ = getElementPosition(player)
    
    local distanceToStart = getDistanceBetweenPoints2D(startX, startY, playerX, playerY)
    
    if not raceInProgress and distanceToStart <= 3 then
        raceInProgress = true
        startTime = getTickCount() -- Start counting time
        outputChatBox("Stage started!", player)
    end
    
    if raceInProgress then
        local elapsedTime = (getTickCount() - startTime) / 1000
        outputChatBox("Stage time: " .. elapsedTime .. " seconds.", player)
    end
    
    if raceInProgress and isElementWithinMarker(player, finishMarker) then
        local elapsedTime = (getTickCount() - startTime) / 1000 
        outputChatBox("Stage finished! Time: " .. elapsedTime .. " seconds.", player)
        raceInProgress = false
    end
end

 

Link to comment
  • Moderators
17 hours ago, 31cmTrueDamage said:

so i guess i am not getting the player position correctly maybe? not sure.

Your initial code looked fine except for a duplicated message when you are in the marker:

Stage time:
Stage finished! Time:

 

Here you have an alternative version + debug lines so that you can validate what is wrong.

View in debug console: /debugscript 3

 

Also keep in mind that this code will not work very good in multiplayer, as startTime, startMarker and finishMarker are shared between all players.

 

You can ignore the ---@ annotations, those are helping me to automatic validate your code. (and perhaps help you to improve readability)

 

----------

-- Add to top of script (local's making sure other scripts can't modify these values by accident)

---@type integer
local startTime = 0

---@type userdata|nil
local startMarker

---@type userdata|nil
local finishMarker

---------

-- ... --

---------

---@param player userdata
function checkStageProgress(player)
    iprint("Validate player", player, isElement(player) and getElementType(player))
    if not isElement(startMarker) or not isElement(finishMarker) then
        iprint("Not startMarker:", isElement(startMarker) and "It exist" or "does not exist", "or not finishMarker:", isElement(finishMarker) and "It exist" or "does not exist")
        return
    end
    
    if not raceInProgress then
        iprint("Race is not in progress")
        local startX, startY, startZ = getElementPosition(startMarker)
        local playerX, playerY, playerZ = getElementPosition(player)
        local distanceToStart = getDistanceBetweenPoints2D(startX, startY, playerX, playerY)

        if distanceToStart <= 3 then
            raceInProgress = true
            startTime = getTickCount() -- Start counting time
            outputChatBox("Stage started!", player)
        end
        return
    end

    -------------------------
    -- Race is in progress --

    local elapsedTime = math.floor((getTickCount() - startTime) / 1000) 
    if isElementWithinMarker(player, finishMarker) then
        outputChatBox("Stage finished! Time: " .. elapsedTime .. " seconds.", player)
        raceInProgress = false
        return
    end
    -----------------------------
    -- Player is not in marker --

    outputChatBox("Stage time: " .. elapsedTime .. " seconds.", player)
end

 

 

Link to comment
  • Moderators
18 minutes ago, 31cmTrueDamage said:

Thank you, sorry to bother, but what recommendations do you have to work better in multiplayer,

For multiplayer you have to store data for each player. And one of the ways to do that is using tables.

 

Here some basic functions you could use.

  • Init the storage first: initPlayerData (onPlayerJoin)
  • And after that you can set and get data from the table, for each player: getPlayerData, setPlayerData
  • When a player disconnects: deletePlayerData (onPlayerQuit)

 

---@type {[userdata]: {[string]: unknown}|nil}
local playerDataCollection = {}

---@param player userdata
---@param key string
---@return unknown|nil
function getPlayerData(player, key)
    local playerData = playerDataCollection[player]
    if not playerData then return end
    return playerData[key]
end

---@param player userdata
---@param key string
---@param value any
function setPlayerData(player, key, value)
    local playerData = playerDataCollection[player]
    if not playerData then return end
    playerData[key] = value
end

--- Create a storage table for data of a specific player
---@param player userdata
function initPlayerData(player)
    if playerDataCollection[player] then return end
    playerDataCollection[player] = {}
end

--- Remove all player data and remove it's storage table
---@param player userdata
function deletePlayerData(player)
    if not playerDataCollection[player] then return end
    playerDataCollection[player] = nil
end

 

 

 

 

Link to comment

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...