• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[Snippet] GameTime

Level 23
Joined
Apr 16, 2012
Messages
4,041
This for sure already appeared here, but I find it semi-useful for things like debug messages or some custom randomization libraries that take seed depending on time and whatnot

JASS:
library GameTime
/*
    made by edo494
    version 1.1
    
    This library provides basic API for getting time in both functional and
    vJass(struct based) style.
    
    This allows you to get current time in raw format in either real(with 3 decimal
    places) or in integer(multiplied) format and set the time to custom value if you so desire.
    
    This method should never revert the returned integer format, because it has period of
    59 hours, 3 minutes, 54 seconds and 836.47 milliseconds, which is more than any game will ever go on for.

    Configurables:
            private constant real PERIOD = 0.003250000

    API:
        struct Time extends array
            
            static method operator integer takes nothing returns integer
                - returns integer representation of the time passed since the beggining of the game
            
            static method operator real takes nothing returns real
                - returns floating point representation of the time passed since the beginning of the game
                
            static method operator hrs takes nothing returns integer
                - returns hours passed since the start of the game
                - this returns the current number in ASCII representation
            
            static method operator min takes nothing returns integer
                - returns minutes passed since the start of the game
                - this returns the current number in ASCII representation
                  so 75 minutes == 15 minutes 1 hour
            
            static method operator sec takes nothing returns integer
                - returns seconds passed since the start of the game
                - this returns the current number in ASCII representation
                  so 75 seconds == 15 seconds 1 minute
            
            static method operator ms takes nothing returns integer
                - returns milliseconds passed since the start of the game
                - this returns the current number in ASCII representation
                  so 1785 milliseconds == 785 milliseconds 1 second
                  
            static method setTimeInt takes integer newTime returns nothing
                - sets new time depending on the newTime(this is the same format as
                  the value returned from operator integer)
                  
            static method setTime takes integer newH, integer newM, integer newS, real newMs returns nothing
                - sets new time to specified number of hours, minuts, seconds and milliseconds
                
        endstruct
        
        functions:
            
            function GetTimeInt takes nothing returns integer
                - returns operator integer
            
            function GetTimeReal takes nothing returns real
                - returns operator real
            
            function SetTime takes integer hours, integer minutes, integer seconds, real ms returns nothing
                - calls Time.setTime
    
            function SetTimeInt takes integer newTime returns nothing
                - calls Time.setTimeInt
    
            function GetHours takes nothing returns integer
                - returns operator hrs
    
            function GetMinutes takes nothing returns integer
                - returns operator min
    
            function GetSeconds takes nothing returns integer
                - returns operator sec
    
            function GetMilliSeconds takes nothing returns real
                - returns operator ms
    
            function GetDifferenceHours takes integer rawTime returns integer
                - Takes integer rawTime in the same format as returned value from
                  GetTimeInt and compares it with the current time
                - returned value is in format of GetHours
    
            function GetDifferenceMinutes takes integer rawTime returns integer
                - Takes integer rawTime in the same format as returned value from
                  GetTimeInt and compares it with the current time
                - returned value is in format of GetMinutes
    
            function GetDifferenceSeconds takes integer rawTime returns integer
                - Takes integer rawTime in the same format as returned value from
                  GetTimeInt and compares it with the current time
                - returned value is in format of GetSeconds
    
            function GetDifferenceMilliseconds takes integer rawTime returns real
                - Takes integer rawTime in the same format as returned value from
                  GetTimeInt and compares it with the current time
                - returned value is in format of GetMilliSeconds
            
*/

//===== Configurables =====

    globals
        private constant real PERIOD = 0.003250000
    globals

//===== End Configurables =====
    private module m
        private static method onUpdate takes nothing returns nothing
            set milliseconds = milliseconds + PERIOD * 1000
            if milliseconds >= 1000. then
                set seconds = seconds + R2I(milliseconds/1000)
                set milliseconds = ModuloInteger(R2I(milliseconds), 1000)
                if seconds >= 60. then
                    set minutes = minutes + seconds/60
                    set seconds = ModuloInteger(seconds, 60)
                    if minutes >= 60. then
                        set hours = hours + minutes/60
                        set minutes = ModuloInteger(minutes, 60)
                    endif
                endif
            endif
        endmethod
        
        private static method onLoad takes nothing returns nothing
            call TimerStart(GetExpiredTimer(), PERIOD, true, function thistype.onUpdate)
        endmethod
        
        private static method onInit takes nothing returns nothing
            call TimerStart(CreateTimer(), 0.00, false, function thistype.onLoad)
        endmethod
    endmodule
    
    struct Time extends array
        readonly static integer hours = 0
        readonly static integer minutes = 0
        readonly static integer seconds = 0
        readonly static real milliseconds = 0
        
        /*
            Reverts in 59 hours, 3 minutes, 54 seconds and 836.47 ms
        */
        static method operator integer takes nothing returns integer
            return R2I(milliseconds * 100) + seconds * 100000 +/*
                    */minutes * 6000000 + hours * 36000000
        endmethod
        
        static method operator real takes nothing returns real
            return milliseconds + I2R(seconds * 1000) +/*
                    */I2R(minutes * 60000) + I2R(hours * 360000)
        endmethod
        
        static method operator hrs takes nothing returns integer
            return hours
        endmethod
        static method operator min takes nothing returns integer
            return minutes
        endmethod
        static method operator sec takes nothing returns integer
            return seconds
        endmethod
        static method operator ms takes nothing returns real
            return milliseconds
        endmethod
        
        static method setTimeInt takes integer newTime returns nothing
            local real reminder = 0
            set hours = newTime / 36000000
            set minutes = (newTime - hours * 36000000) / 6000000
            set seconds = (((newTime - hours * 36000000) / 6000000) - minutes * 6000000) / 100000
            set milliseconds = ((((newTime - hours * 36000000) / 6000000) - minutes * 6000000) / 100000) - seconds * 100000
        endmethod
        
        static method setTime takes integer newH, integer newM, integer newS, real newMs returns nothing
            set hours = newH
            set minutes = newM
            set seconds = newS
            set milliseconds = newMs
        endmethod
        
        implement m
    endstruct
    
    function GetTimeInt takes nothing returns integer
        return Time.integer
    endfunction
    
    function GetTimeReal takes nothing returns real
        return Time.real
    endfunction
    
    function SetTime takes integer hours, integer minutes, integer seconds, real ms returns nothing
        call Time.setTime(hours, minutes, seconds, ms)
    endfunction
    
    function SetTimeInt takes integer newTime returns nothing
        call Time.setTimeInt(newTime)
    endfunction

    function GetHours takes nothing returns integer
        return Time.hours
    endfunction
    
    function GetMinutes takes nothing returns integer
        return Time.minutes
    endfunction
    
    function GetSeconds takes nothing returns integer
        return Time.seconds
    endfunction
    
    function GetMilliSeconds takes nothing returns real
        return Time.milliseconds
    endfunction
    
    function GetDifferenceHours takes integer rawTime returns integer
        local integer i = Time.integer
        local integer q = Time.hrs
        call Time.setTimeInt(rawTime)
        set q = Time.hrs - q
        call Time.setTimeInt(i)
        return q
    endfunction
    
    function GetDifferenceMinutes takes integer rawTime returns integer
        local integer i = Time.integer
        local integer q = Time.min
        call Time.setTimeInt(rawTime)
        set q = Time.min - q
        call Time.setTimeInt(i)
        return q
    endfunction
    
    function GetDifferenceSeconds takes integer rawTime returns integer
        local integer i = Time.integer
        local integer q = Time.sec
        call Time.setTimeInt(rawTime)
        set q = Time.sec - q
        call Time.setTimeInt(i)
        return q
    endfunction
    
    function GetDifferenceMilliseconds takes integer rawTime returns real
        local integer i = Time.integer
        local real q = Time.ms
        call Time.setTimeInt(rawTime)
        set q = Time.ms - q
        call Time.setTimeInt(i)
        return q
    endfunction
    
endlibrary

I know it could use CTL, but meh its just one timer
 
Last edited:
This is more efficient (and not optimized), but I need to find a way for it to function when game speed (or time) has changed.

JASS:
library GameTime

    struct GameTime
        
        static method Now takes nothing returns real
            return GetFloatGameState(GAME_STATE_TIME_OF_DAY)
        endmethod
        
        static method Milliseconds takes nothing returns real
            return ((GetFloatGameState(GAME_STATE_TIME_OF_DAY) * (GetTimeOfDayScale() * 10)) / 5)
        endmethod
        
        static method Seconds takes nothing returns integer
            return R2I(thistype.Milliseconds() * 10)
        endmethod
        
        static method Minutes takes nothing returns integer
            return R2I((thistype.Seconds()) / 60)
        endmethod
        
        static method Hours takes nothing returns integer
            return R2I((thistype.Minutes()) / 60)
        endmethod
        
        static method Days takes nothing returns integer
            return R2I((thistype.Hours()) / 24)
        endmethod

    endstruct
    
endlibrary


JASS:
scope Test initializer onInit

    globals
        private constant real INTERVAL = .1
        private real c = INTERVAL
        private real s = 0
    endglobals
    
    private function Display takes nothing returns nothing
        call ClearTextMessages()
        
        call BJDebugMsg("Milliseconds: " + R2S((GameTime.Milliseconds())))
        call BJDebugMsg("Seconds: " + I2S(GameTime.Seconds()))
        call BJDebugMsg("Minutes: "   + I2S(R2I(GameTime.Minutes())))
        
        call BJDebugMsg("\n\n" + R2S(GetTimeOfDayScale()) + "\n\n")
        
        call BJDebugMsg("\n\nTimer Milliseconds: " + R2S(c/10))
        call BJDebugMsg("Timer Seconds: " + I2S(    R2I(c)  ))
        call BJDebugMsg("Timer Minutes: " + I2S(    R2I(c/60)  ))
        
        set c = c + INTERVAL
    endfunction
    
    private function onInit takes nothing returns nothing
        call TimerStart(CreateTimer(), INTERVAL, true, function Display)
    endfunction
    
endscope
 
Last edited:
Level 23
Joined
Apr 16, 2012
Messages
4,041
triggerhappy isnt your code quite a bit different?
Mine measures real life time since the start of game so thats why 0.00325 s timer, and while time ingame changes, time in real life does not

maybe I called it wrong way
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
well I will but Im on mobile right now

but I see no problem with executing like 3 lines per 0.00325 seconds, look at GUI users, they execute group enums within the same period

but from what I can see on mobile, wont this return the ingame time? as in 18 hours when it gets to night etc?
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
well yea the problem is you cant scroll Jass script on mobile so in milliseconds I dont even see the name of second function(GetTimeOfDayS border)
:D

however, calling hours returns global variable in mine, in yours it recursivelly calls like 5 functions + 2+(cant see there :D) natives

also I plan using my script to randomize the drops of monsters so the GetTimeInt comes in handy here for seeding the RNG
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
TriggerHappy said:
This is more efficient (and not optimized), but I need to find a way for it to function when game speed (or time) has changed.

I suppose you can change them only with triggers ? If it's that, then the answer is obvious, either hooks or custom functions + a timer started since the begin.

I don't think there is an other way, because "all" change together with the game speed, included timers.
And also you can't know how many time the game was at speed "X" and at speed "Y".
 
well I will but Im on mobile right now

but I see no problem with executing like 3 lines per 0.00325 seconds, look at GUI users, they execute group enums within the same period

but from what I can see on mobile, wont this return the ingame time? as in 18 hours when it gets to night etc?

That still doesn't change the fact that it's being set every 0.03 seconds.
And yes, I realize the calls are recursive, which is why I said it's not optimized yet.

Anyway, another issue with my script I would assume that it only works for one whole day in the game, without some lame workaround.
 
Anyway, another issue with my script I would assume that it only works for one whole day in the game, without some lame workaround.

That's kind of why it does a completely different thing ;v

~~~
You can probably use a timer that fires every 'day' and have it change some internal state. (An integer representing the number of days passed)
 
That's kind of why it does a completely different thing ;v

How does that make it a completely different thing?
The outcome is the same on both scripts.

~~~
You can probably use a timer that fires every 'day' and have it change some internal state. (An integer representing the number of days passed)

Eh, the traditional way is probably the best (periodic timer).
 
Top