• 🏆 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!

[vJASS] [Snippet] IsDayNight

Level 5
Joined
Mar 15, 2017
Messages
96
A simplified day or night detection with Register Event...
vJASS:
library IsDayNight/* v1.1.0
****************************************************************************************************
*                                       Is Day or Night
*                                      By: BloodForBlood
*
*       A simple day or night detector.
*
*       How to Implement:
*           Copy the dummy unit(TimeIdentifier) to your map
*           then copy this library.Or use the ObjectMerger
*           above "globals".
*
*       API:
*           function IsDay takes nothing returns boolean
*           function IsNight takes nothing returns boolean
*           function RegisterDayEvent takes code c returns nothing
*           function RegisterNightEvent takes code c returns nothing
*
*       Credits:
*           Bannar - for giving me a dummy unit idea
*           Original Creator - if there are an original creator of IsDayNight
*           Wareditor - for the Dummy Unit ObjectMerger script
*
***************************************************************************************************/
// external ObjectMerger w3u hpea uNyt ufoo 0 uabi Aloc,Ambt umdl " " usca 0 ushu " " unam "TimeIdentifier" unsf "(IsDayNight)" util 0 uhpm 100 uhpr 100 uhrt "day" umpm 100 umpi 1 umpr 100
    globals
        private constant integer IDENTIFIER_ID = 'uNyt' // Change this to the proper id of the dummy
      //==============Dont Modify Below==============
        private boolean BOOL = false
        private unit DUMMY
        private trigger array TRIG
        private boolean array EVENT
    endglobals

    function IsDay takes nothing returns boolean
        return BOOL
    endfunction

    function IsNight takes nothing returns boolean
        return not BOOL
    endfunction

    function RegisterDayEvent takes code c returns nothing
        call TriggerAddCondition(TRIG[1], Filter(c))
    endfunction

    function RegisterNightEvent takes code c returns nothing
        call TriggerAddCondition(TRIG[2], Filter(c))
    endfunction
 
    private function identifierNight takes nothing returns boolean
        set BOOL = false
        if (not EVENT[2]) then
            set EVENT[1] = false
            set EVENT[2] = true
            call TriggerEvaluate(TRIG[2])
        endif
        call SetUnitState(DUMMY, UNIT_STATE_MANA, 1)
        return false
    endfunction
 
    private function identifierDay takes nothing returns boolean
        set BOOL = true
        if (not EVENT[1]) then
            set EVENT[1] = true
            set EVENT[2] = false
            call TriggerEvaluate(TRIG[1])
        endif
        call SetWidgetLife(DUMMY, 1)
        return false
    endfunction

    private module m
        private static method onInit takes nothing returns nothing
            local rect r = GetWorldBounds()
            local trigger t = CreateTrigger()
            set TRIG[1] = CreateTrigger()
            set TRIG[2] = CreateTrigger()
            set DUMMY = CreateUnit(Player(15), IDENTIFIER_ID, GetRectMaxX(r), GetRectMaxY(r), 0)
            call SetWidgetLife(DUMMY, 1)
            call SetUnitState(DUMMY, UNIT_STATE_MANA, 1)
            call PauseUnit(DUMMY, true)
            call ShowUnit(DUMMY, false)
            call TriggerRegisterUnitStateEvent(t, DUMMY, UNIT_STATE_LIFE, GREATER_THAN_OR_EQUAL, 2)
            call TriggerAddCondition(t, Condition(function identifierDay))
            set t = CreateTrigger()
            call TriggerRegisterUnitStateEvent(t, DUMMY, UNIT_STATE_MANA, GREATER_THAN_OR_EQUAL, 2)
            call TriggerAddCondition(t, Condition(function identifierNight))
            call RemoveRect(r)
            set r = null
            set t = null
        endmethod
    endmodule

    private struct s
        implement m
    endstruct

endlibrary
Demo:
vJASS:
scope Demo initializer onInit

    private function day takes nothing returns nothing
        call BJDebugMsg("It's morning,wake up!")
    endfunction

    private function night takes nothing returns nothing
        call BJDebugMsg("It's nighttime,time to sleep!")
    endfunction
 
    private function esc takes nothing returns nothing
        if (IsDay()) then
            call BJDebugMsg("Day")
        endif
        if (IsNight()) then
            call BJDebugMsg("Night")
        endif
    endfunction

    private function onInit takes nothing returns nothing
        local trigger t = CreateTrigger()
        if (IsNight()) then
            call FogEnable(false)
            call FogMaskEnable(false)
        endif
        call RegisterDayEvent(function day)
        call RegisterNightEvent(function night)
        call TriggerRegisterPlayerEvent(t, Player(0), EVENT_PLAYER_END_CINEMATIC)
        call TriggerAddAction(t, function esc)
        call BJDebugMsg("Press ESC to test IsDay/IsNight functions")
    endfunction

endscope
Thanks to Banaar for telling me to use modules instead of initializer
 

Attachments

  • IsDayNight NonTimer.w3x
    84.3 KB · Views: 57
Last edited:

Bannar

Code Reviewer
Level 26
Joined
Mar 19, 2008
Messages
3,140
This is plain wrong. My day time boundaries might be different than 6 AM and 18 PM. What happens then?

Instead you use a dummy unit that has its life or mana reg based on time of the day (day/ night) and register to state-change event. That's all that is to the subject.
Whatmore, such approach allows you to expose Day/ Night events op top of IsDay/IsNight function.
Unfortunately, it's not like I'm making this out of the box. This has been done already ; ( Maybe someone removed it from hive.
Modders these days.. Kappa.
 

Jampion

Code Reviewer
Level 15
Joined
Mar 25, 2016
Messages
1,327
I think this could be done in one function:
JASS:
function IsDay takes nothing returns boolean
    local real r = GetFloatGameState(GAME_STATE_TIME_OF_DAY)
    return r >= 6 or r < 18
endfunction

Your implementaion will not work at the beginning of the map. At the beginning it will always return false, as periodic only runs 0.03125 seconds after that.

Using timer utils does not make much sense in this case. TimerUtils recycles timers and allows you to bind an integer to them. Neither of it is used here, as the timer is never removed.
 
Level 5
Joined
Mar 15, 2017
Messages
96
I think this could be done in one function:
JASS:
function IsDay takes nothing returns boolean
    local real r = GetFloatGameState(GAME_STATE_TIME_OF_DAY)
    return r >= 6 or r < 18
endfunction

Your implementaion will not work at the beginning of the map. At the beginning it will always return false, as periodic only runs 0.03125 seconds after that.

Using timer utils does not make much sense in this case. TimerUtils recycles timers and allows you to bind an integer to them. Neither of it is used here, as the timer is never removed.
WTF?!I didn't think of that!OMG!

This is plain wrong. My day time boundaries might be different than 6 AM and 18 PM. What happens then?

Instead you use a dummy unit that has its life or mana reg based on time of the day (day/ night) and register to state-change event. That's all that is to the subject.
Whatmore, such approach allows you to expose Day/ Night events op top of IsDay/IsNight function.
Unfortunately, it's not like I'm making this out of the box. This has been done already ; ( Maybe someone removed it from hive.
Modders these days.. Kappa.
You gaved me an idea,but my goal is to make it lightweight(don't need any units or abilities).But I think it's the best way.

Unfortunately, it's not like I'm making this out of the box. This has been done already
Who made that one?
 
Last edited by a moderator:

Bannar

Code Reviewer
Level 26
Joined
Mar 19, 2008
Messages
3,140
I don't remember original author. It was like 8 years ago mate. I have a copy of some kind myself.
And that solution is lightweight, trust me = )
If I'd couple it with RegisterNativeEvent, then it is even lighter - remember, what we talk about is IsDay/Night + Day/Night events. IsDay/Night alone is too little, those two features should not be separated.
 
Level 5
Joined
Mar 15, 2017
Messages
96
I don't remember original author. It was like 8 years ago mate. I have a copy of some kind myself.
And that solution is lightweight, trust me = )
If I'd couple it with RegisterNativeEvent, then it is even lighter - remember, what we talk about is IsDay/Night + Day/Night events. IsDay/Night alone is too little, those two features should not be separated.
I actually added day/night events,but I didn't include it..

And that solution is lightweight, trust me = )
Well,what I mean:I should not use any object data.But...Ugh
 
Last edited:

Jampion

Code Reviewer
Level 15
Joined
Mar 25, 2016
Messages
1,327
You could use constants to configure day and night time. This is less work than creating an additional unit type.
Even if you use object merger, restarting the editor takes longer than writing two values.

Also I don't think using a unit is as lightweight as using a function and game state events.
JASS:
TriggerRegisterGameStateEvent
 

Bannar

Code Reviewer
Level 26
Joined
Mar 19, 2008
Messages
3,140
And what about custom night? Moonstone?
UnitIndexers are already there. Do you think 1 more dummy given our current PC resources is not "lightweight"? Ofc, if there is non-dummy solution which is as accurate as dummy one, I'm in.

Portability is key factor for me. Globals to modify - not as portable.
 
Level 5
Joined
Mar 15, 2017
Messages
96
Yeah, what I had in mind is ObjectMerger usage - everything would be part of the snippet. No custom object data to copy manually.
But I don't know how to create ObjectMerger scripts.LOL!
So these snippet needs to copy the unit manually.

I think this is better:
vJASS:
    private function identifier takes nothing returns nothing
        if (GetUnitState(DUMMY, UNIT_STATE_LIFE) < GetUnitState(DUMMY, UNIT_STATE_MAX_LIFE)) then
            set bool = false // Night
            call SetUnitState(DUMMY, UNIT_STATE_LIFE, GetUnitState(DUMMY, UNIT_STATE_MAX_LIFE))
            return
        endif
        set bool = true // Day
    endfunction
The dummy unit only hp regenerates at night with -100 regen.
 
Last edited by a moderator:
Level 14
Joined
Jan 16, 2009
Messages
716
Reinventing the wheel #256

Bonus:
JASS:
//! textmacro GenerateDayNightEventAssets takes DAYID, NIGHTID
    //! external ObjectMerger w3u hpea $DAYID$ ufoo 0 uabi Avul,Aloc umdl " " usca 0 ushu " " unam "DayDetect" unsf "(DNE Dummy)" util 0 uhpm 5 uhpr 100 uhrt "day"
    //! external ObjectMerger w3u hpea $NIGHTID$ ufoo 0 uabi Avul,Aloc umdl " " usca 0 ushu " " unam "NightDetect" unsf "(DNE Dummy)" util 0 uhpm 5 uhpr 100 uhrt "night"
//! endtextmacro
 
Level 5
Joined
Mar 15, 2017
Messages
96
Reinventing the wheel #256

Bonus:
JASS:
//! textmacro GenerateDayNightEventAssets takes DAYID, NIGHTID
    //! external ObjectMerger w3u hpea $DAYID$ ufoo 0 uabi Avul,Aloc umdl " " usca 0 ushu " " unam "DayDetect" unsf "(DNE Dummy)" util 0 uhpm 5 uhpr 100 uhrt "day"
    //! external ObjectMerger w3u hpea $NIGHTID$ ufoo 0 uabi Avul,Aloc umdl " " usca 0 ushu " " unam "NightDetect" unsf "(DNE Dummy)" util 0 uhpm 5 uhpr 100 uhrt "night"
//! endtextmacro
Thanks!I really don't know those macro things.
 
Level 5
Joined
Mar 15, 2017
Messages
96
Reinventing the wheel #256

Bonus:
JASS:
//! textmacro GenerateDayNightEventAssets takes DAYID, NIGHTID
    //! external ObjectMerger w3u hpea $DAYID$ ufoo 0 uabi Avul,Aloc umdl " " usca 0 ushu " " unam "DayDetect" unsf "(DNE Dummy)" util 0 uhpm 5 uhpr 100 uhrt "day"
    //! external ObjectMerger w3u hpea $NIGHTID$ ufoo 0 uabi Avul,Aloc umdl " " usca 0 ushu " " unam "NightDetect" unsf "(DNE Dummy)" util 0 uhpm 5 uhpr 100 uhrt "night"
//! endtextmacro

You could use constants to configure day and night time. This is less work than creating an additional unit type.
Even if you use object merger, restarting the editor takes longer than writing two values.

Also I don't think using a unit is as lightweight as using a function and game state events.
JASS:
TriggerRegisterGameStateEvent

And Nes is not even the original author :X
The first one was done with moon wells, way before. Nes improved it.

EDIT: UPDATED!
And I hope this is better.
 
Last edited:
Level 5
Joined
Mar 15, 2017
Messages
96
As a micro-optimization, why not use

JASS:
native GetWidgetLife(widget w) returns real
native SetWidgetLife(widget w, real r)

instead of GetUnitState and SetUnitState?
Okay,I forgot..

You do not need timer at all. Add RegisterNativeEvent so you don't have to declare triggers and register functions yourself.
Hmm,fine.

Edit: UPDATED!
You do not need timer at all. Add RegisterNativeEvent so you don't have to declare triggers and register functions yourself.
Removed timer requirement.

As a micro-optimization, why not use

JASS:
native GetWidgetLife(widget w) returns real
native SetWidgetLife(widget w, real r)

instead of GetUnitState and SetUnitState?
Used Get/SetWidgetLife.
Paghirot han imo Baba, idoy!
Woah, wait... Where do you live?In the Philippines?Where?What's the name of the city?
 
Last edited:
It doesn't seem to work properly. Sometimes it will spam the event causing the game to hang, and sometimes it reports the wrong value. Furthermore it's not much better than a timer. Code is still executing every X seconds (regen time) and it requires a dummy unit. If this were working properly it could be useful due to it theoretically being able to detect any edge-case of the game turning to night, however it's not very efficient.

If Moonstone is the only feature that changes the game to night other than the default DNC, then I would personally use constants, the game state events, and events for when/if a Moonstone is used. However that's not really suitable for a public library, so I suppose this will do if you can make sure it's working properly.
 

Attachments

  • wrong.png
    wrong.png
    613.2 KB · Views: 77

Jampion

Code Reviewer
Level 15
Joined
Mar 25, 2016
Messages
1,327
Moonstone sets the time of day to 0 and pauses the day night cycle.

JASS:
    call TriggerRegisterGameStateEvent(trig, GAME_STATE_TIME_OF_DAY, GREATER_THAN_OR_EQUAL, 18.)
    call TriggerRegisterGameStateEvent(trig, GAME_STATE_TIME_OF_DAY, LESS_THAN, 6.)

This trigger will fire, when it becomes night (also for Moonstone). I don't know if there are any other ways to make it night, but I think all of them must change the time of day and would be caught by the GameStateEvent.

You can use these events to set a boolean isDay that is returned by a function.


The user would have to configure day and night times, but it will be very simple compared to the dummy unit approach.
 
Level 5
Joined
Mar 15, 2017
Messages
96
It doesn't seem to work properly. Sometimes it will spam the event causing the game to hang, and sometimes it reports the wrong value. Furthermore it's not much better than a timer. Code is still executing every X seconds (regen time) and it requires a dummy unit. If this were working properly it could be useful due to it theoretically being able to detect any edge-case of the game turning to night, however it's not very efficient.

If Moonstone is the only feature that changes the game to night other than the default DNC, then I would personally use constants, the game state events, and events for when/if a Moonstone is used. However that's not really suitable for a public library, so I suppose this will do if you can make sure it's working properly.
So, you mean I will bring back my old library that does not use a dummy unit and just modify the constants for day and night time?
 
So, you mean I will bring back my old library that does not use a dummy unit and just modify the constants for day and night time?

I tested it and the game state events also detect Moonstone, so I'm not sure why people thought there was a need for a dummy unit. If the library can work with any custom gameplay constants and Moonstone then I think it would be a better solution. Although please thoroughly test it to make sure it's working properly.
 
Level 5
Joined
Mar 15, 2017
Messages
96
I tested it and the game state events also detect Moonstone, so I'm not sure why people thought there was a need for a dummy unit. If the library can work with any custom gameplay constants and Moonstone then I think it would be a better solution. Although please thoroughly test it to make sure it's working properly.
I tested it, but can you tell me how did you do the bug?
 
So I can only see two ways this resource would go:

Simple -> Easy to import, and configure.

Automatic -> More convoluted, and may not fully work, but no input from users. A plug and play, of sorts.

Thinking about all possible cases, the simple approach is ultimately more convenient, assuming that the user only needs to tweak it once, so going simple is the more conventional approach.
 
I tested it, but can you tell me how did you do the bug?

The bug only occurred with the dummy unit approach. I don't remember exactly how I caused the bug but it wasn't hard to reproduce in my testings.

If you are planning to change the system to use constants then it's irrelevant anyway. Of course make sure to thoroughly test the implementation to make sure it works correctly under different gameplay constants and scenarios.
 
Level 5
Joined
Mar 15, 2017
Messages
96
The bug only occurred with the dummy unit approach. I don't remember exactly how I caused the bug but it wasn't hard to reproduce in my testings.

If you are planning to change the system to use constants then it's irrelevant anyway. Of course make sure to thoroughly test the implementation to make sure it works correctly under different gameplay constants and scenarios.
Yep, I removed the unit this time.But I will not post it right now, because I still have problems on event.
 
Level 18
Joined
Nov 21, 2012
Messages
835
I am using this for night detection in my maps (for standard dawn/dusk time), maybe you found it usefull
JASS:
function Trg_DayOn takes nothing returns nothing
    if GetFloatGameState(GAME_STATE_TIME_OF_DAY) < 18.00 then
        set isDay=true
        call MsgDev("DAY is ON")
    endif
endfunction
//------------------------------------------------------------------
 function Trg_NightOn takes nothing returns nothing
    set isDay=false
    call MsgDev("NIGHT is ON")
endfunction
//========================================================
function InitTrig_Environment takes nothing returns nothing
    //--------
    set trg_dayON = CreateTrigger()
    call TriggerRegisterGameStateEventTimeOfDay( trg_dayON, GREATER_THAN_OR_EQUAL, 6.00 )
    call TriggerAddAction( trg_dayON, function Trg_DayOn )
    //--------
    set trg_nightON = CreateTrigger()
    call TriggerRegisterGameStateEventTimeOfDay( trg_nightON, EQUAL, 18.00 )
    call TriggerRegisterGameStateEventTimeOfDay( trg_nightON, EQUAL, 0.00 )
    call TriggerAddAction( trg_nightON, function Trg_NightOn )
endfunction
 
Level 5
Joined
Mar 15, 2017
Messages
96
I am using this for night detection in my maps (for standard dawn/dusk time), maybe you found it usefull
JASS:
function Trg_DayOn takes nothing returns nothing
    if GetFloatGameState(GAME_STATE_TIME_OF_DAY) < 18.00 then
        set isDay=true
        call MsgDev("DAY is ON")
    endif
endfunction
//------------------------------------------------------------------
 function Trg_NightOn takes nothing returns nothing
    set isDay=false
    call MsgDev("NIGHT is ON")
endfunction
//========================================================
function InitTrig_Environment takes nothing returns nothing
    //--------
    set trg_dayON = CreateTrigger()
    call TriggerRegisterGameStateEventTimeOfDay( trg_dayON, GREATER_THAN_OR_EQUAL, 6.00 )
    call TriggerAddAction( trg_dayON, function Trg_DayOn )
    //--------
    set trg_nightON = CreateTrigger()
    call TriggerRegisterGameStateEventTimeOfDay( trg_nightON, EQUAL, 18.00 )
    call TriggerRegisterGameStateEventTimeOfDay( trg_nightON, EQUAL, 0.00 )
    call TriggerAddAction( trg_nightON, function Trg_NightOn )
endfunction
Thanks for the idea. ;)
 
Top