System DayNightFog system

Viikuna

No Marlo no game.
Reaction score
265
edit

I made this script back in the day when I didnt completely understamd what you exactly can do asynchronously and what you cant.

Since Im not planning to update this to make it to what it is supposed to be, I just link to guys to best fog system I know. Use it instead. Link: RegionalFog ( It has day night cycle thingies too now. )


endedit


I once had a nice script which changed terrain fog overtime, because I liked to have a blue fog for night and some other fog for day.

Now I have written a new version, which also supports different fogs for different players.
Requires vJass compiler thingy.

The usage is pretty simple:

JASS:
    
local fog f1=fog.create(76.4,81.2,83.1,0.0,12000.)
local fog f2=fog.create(12.1,16.4,73.1,0.0,3500.)

// You can create these fog objects, which hold fogs color and z values and
// changeDuration.
// ( How long it takes to change from current fog to this fog )

set PlayerFogData[0].useFog=true
set PlayerFogData[0].day=f1
set PlayerFogData[0].night=f2

// Im using an array struct for PlayerFogData
// ( Use player number as an array index )
// There is 3 fog slots for fogs: day, night and special. 
// You can use special by setting useSpecial=true
// System only reads values from day, night and special, 
// so they wont change unless you change them

call SetTimeOfDay(10.0)
call PlayerFogData[0].refresh(true)
// method refresh is used to change to current fog ( day, night or special )
// it takes boolean instant: true = fog changes instantly,
//  false = changes over fog.changeDuration

// refresh( false ) is also called for every player every sun set and every sun rise.


Note that this system uses GameStateEvents to find out is it Day or Night.
Because Bob_The_Kodo in wc3c.net says that GameStateEvents are pretty awful, I might update this to use periodic timer later.

Anyways, give me comments.

System code:
edit.

.0.1 edited code a little. I made it use color values between 0. and 100. , instead of 0. and 1. , because Jass fails with small values.

.0.2 fixed .refresh(true). It now stops overtime fog changing.

JASS:
library DayNightFog

//   version 1.0.2


globals
    private constant real DAWN_TIME = 6.00
    private constant real DUSK_TIME = 18.00
    private constant real TIMEOUT = .03
    // For initial day time:
    private constant boolean IT_IS_DAY = false
    private constant real INITIAL_FOG_CHANGE_DURATION = 10.
endglobals

//=======================================================================
// Fog System includes:
//                 -struct fog
//                         - color and z values
//                           and change duration
//                         - method copyValues takes fog source
//
//                 -array struct PlayerFogData
//                         - fog day
//                         - fog night
//                         - fog special
//                         - boolean useSpecial
//                         - boolean useFog
//                         - method refresh takes boolean instant
//                        ( refresh(true) means that fog changes instantly )
//                        ( refresh(false) means that fog changes over fogs changeDuration time ) 
// 
//
//=======================================================================
//=======================================================================
struct fog
    real red
    real green
    real blue
    real zstart
    real zend
    real changeDuration
    
    static method create takes real red, real green, real blue, real zstart, real zend returns fog
        local fog f=fog.allocate()
        set f.red=red
        set f.green=green
        set f.blue=blue
        set f.zstart=zstart
        set f.zend=zend
        set f.changeDuration=INITIAL_FOG_CHANGE_DURATION
        return f
    endmethod
    
    method copyValues takes fog source returns nothing
        set .red=source.red
        set .green=source.green
        set .blue=source.blue
        set .zstart=source.zstart
        set .zend=source.zend
        set .changeDuration=source.changeDuration
    endmethod
endstruct
//=======================================================================
struct PlayerFogData extends array
//=======================================================================
    fog day
    fog night
    fog special
    boolean useSpecial
    boolean useFog
    
    private static boolean IsDay=IT_IS_DAY  
   method operator isDay takes nothing returns boolean
      return .IsDay
   endmethod
   
//====================================================== 
//======================================================     
    private integer id
    private fog now
    private fog velocity
    private fog target
    private integer iterations
    private boolean change
    private static timer T=CreateTimer()
    private static boolean timer=false
    private static trigger Dawn=CreateTrigger()
    private static trigger Dusk=CreateTrigger()
    
    method refresh takes boolean instant returns nothing
        local fog f
        local real red
        local real blue
        local real green
        local real zstart
        local real zend
        if .useFog then
            if .useSpecial and integer(.special)!=0 then
                set f=.special
            else
                if .IsDay and integer(.day)!=0 then
                    set f=.day
                else
                    if integer(.night)!=0 then
                        set f=.night 
                    endif
                endif
            endif
            if integer(f)!=0 then
                if instant then
                    call .target.copyValues(f)
                    call .now.copyValues(f)
                    if .change then
                        set .iterations=0
                        set .change=false
                    endif
                    set red=.now.red
                    set blue=.now.blue
                    set green=.now.green
                    set zstart=.now.zstart
                    set zend=.now.zend
                    if GetLocalPlayer()==Player(.id) then
                        call SetTerrainFogEx(0,zstart,zend,0.0,red*0.01,green*0.01,blue*0.01)
                    endif
                else
                    set .iterations=R2I(f.changeDuration/TIMEOUT)
                    call .target.copyValues(f)
                    set .velocity.red=(.target.red-.now.red)/.iterations
                    set .velocity.green=(.target.green-.now.green)/.iterations
                    set .velocity.blue=(.target.blue-.now.blue)/.iterations
                    set .velocity.zstart=(.target.zstart-.now.zstart)/.iterations
                    set .velocity.zend=(.target.zend-.now.zend)/.iterations
                    set .change=true
                    if not .timer then
                        set .timer=true
                        call TimerStart(.T,TIMEOUT,true,function PlayerFogData.periodic)
                    endif
                endif
            endif
        endif
    endmethod
    
    //! textmacro Limits takes VALUE
        if $VALUE$ > 100. then
           set $VALUE$=100.
        else
           if $VALUE$ < 0. then
              set $VALUE$=0.
           endif
        endif
    //! endtextmacro
    
    private static method periodic takes nothing returns nothing
        local integer i=0
        local integer endcount=12
        local PlayerFogData f
        local real red
        local real blue
        local real green
        local real zstart
        local real zend
        loop
           exitwhen i>11
           set f=PlayerFogData<i>
           if f.change and f.useFog then
               if f.iterations&gt;0 then
                   set f.iterations=f.iterations-1
                   set red=f.now.red+f.velocity.red
                   set green=f.now.green+f.velocity.green
                   set blue=f.now.blue+f.velocity.blue
                   set zstart=f.now.zstart+f.velocity.zstart
                   set zend=f.now.zend+f.velocity.zend
               else
                   set f.change=false
                   set red=f.target.red
                   set blue=f.target.blue
                   set green=f.target.green
                   set zstart=f.target.zstart
                   set zend=f.target.zend
               endif
               //! runtextmacro Limits(&quot;red&quot;)
               //! runtextmacro Limits(&quot;green&quot;)
               //! runtextmacro Limits(&quot;blue&quot;)
               if GetLocalPlayer()==Player(i) then
                   call SetTerrainFogEx(0,zstart,zend,0.0,red*0.01,green*0.01,blue*0.01)
               endif
               set f.now.red=red
               set f.now.green=green
               set f.now.blue=blue
               set f.now.zstart=zstart
               set f.now.zend=zend
           else
              if f.change and not f.useFog then
                 set f.change=false
              endif
              set endcount=endcount-1
              if endcount==0 then
                  call PauseTimer(.T)
                  set .timer=false
              endif
           endif
           set i=i+1
         endloop
    endmethod
    
    private static method IsItDawnYet takes nothing returns boolean
        local integer i=0
        set .IsDay=true
        loop
            exitwhen i&gt;11
            call PlayerFogData<i>.refresh(false)
            set i=i+1
        endloop
        return false
    endmethod
    private static method IsItDuskYet takes nothing returns boolean
        local integer i=0
        set .IsDay=false
        loop
            exitwhen i&gt;11
            call PlayerFogData<i>.refresh(false)
            set i=i+1
        endloop
        return false
    endmethod
    
    private static method onInit takes nothing returns nothing
        local integer i=0
        loop
            exitwhen i&gt;11
            set PlayerFogData<i>.useSpecial=false
            set PlayerFogData<i>.change=false
            set PlayerFogData<i>.useFog=false
            set PlayerFogData<i>.iterations=0
            set PlayerFogData<i>.now=fog.create(0.0,0.0,0.0,0.0,0.0)
            set PlayerFogData<i>.velocity=fog.create(0.0,0.0,0.0,0.0,0.0)
            set PlayerFogData<i>.target=fog.create(0.0,0.0,0.0,0.0,0.0)
            set PlayerFogData<i>.id=i
            set i=i+1
        endloop
        call TriggerRegisterGameStateEvent(.Dawn,GAME_STATE_TIME_OF_DAY,EQUAL,DAWN_TIME)
        call TriggerRegisterGameStateEvent(.Dusk,GAME_STATE_TIME_OF_DAY,EQUAL,DUSK_TIME)
        call TriggerAddCondition(.Dawn,Condition(function PlayerFogData.IsItDawnYet))
        call TriggerAddCondition(.Dusk,Condition(function PlayerFogData.IsItDuskYet))
    endmethod
endstruct

endlibrary</i></i></i></i></i></i></i></i></i></i></i>
 

Attachments

  • DayNightFog 1.0.2.w3x
    45.7 KB · Views: 242

Viikuna

No Marlo no game.
Reaction score
265
True, I add one tomorrow.

okay, added a test map to first post.
 

D.V.D

Make a wish
Reaction score
73
So all this those is sets the fog different when its night and day or those it change slowly or something?
 

Viikuna

No Marlo no game.
Reaction score
265
I dont know, you know.


( If you want to know what this does, read the code. If you dont understand it, play the test map. It has different fogs for different regions ans stuff like that )
 

D.V.D

Make a wish
Reaction score
73
I tested the map. It has one fog across the whole map. Im not good with vJass code.
 

Zwiebelchen

You can change this now in User CP.
Reaction score
60
@ DVD: If I understood correctly this is a general system that changes fog on day/night or whenever you want it for a single player, not for everyone on the map. Which is pretty useful, since GetLocalPlayer() is very difficult and dangerous to use if you don't know what you are doing.


I didn't check the demomap since i dont have wc3 here on this pc; but I think it will be pretty useful and if it works; i'm definitly gonna use this on my map.
So you can use the special fog anytime whenver u use the "useSpecial = true" command? Amazing for dungeon fogs then.

anyways; +rep

PS: One question: If you use a transition time between fog changes, will both transition time variables be used? Lets say I use for the night fog a time of 1000 and for the day fog a time of 5000, how long will be the transition time? Will night fade out after 1000 and simultanously, day fade in for 5000? Or will both change smoothly for 5000?
 

Viikuna

No Marlo no game.
Reaction score
265
Each fog struct has a real changeDuration, which tells how long it takes to change from current fog ( whatever it is ) to this fog.

So if it changes from day to night, only nigths changeDuration matters.

And changeDuration is in seconds btw.

I tested the map. It has one fog across the whole map. Im not good with vJass code.

You can only have one fog per player and its always for whole map. Actually, BuilderBob made a pretty neat DynamicAmbiance system. The problem is that it uses Camera Data, which is local data, so its kinda hard to make MPI. Local Data can be syncd, but it is slow, and camera moves really fast..

Anyone knows if having different values in global variable desyncs, if you only use that blobal inside GetLocalPlayer ?
 

Zwiebelchen

You can change this now in User CP.
Reaction score
60
I don't have much to criticize on that.

Just one suggestion: Make those color values adjustable between 0 and 255 instead of 0 and 100. You can get a better "preview" like that in the editor (which uses 0-255 range in the map settings).
 

Zwiebelchen

You can change this now in User CP.
Reaction score
60
Found a bug ... or better: Something you didn't thought of when creating the system.

When you change the fog instantly to special via using .refresh(true) during the transition time of day/night fog, it creates a weird fog until the transition time is over.
 

Viikuna

No Marlo no game.
Reaction score
265
Yea, it is a bug in instant refreshing script. It does not change target values.

I fixd it now and it should work fine. I will post new test map and script later today, after I have done some more testing.

Hm.. maybe I should use version numbers and make some change log..
 

Viikuna

No Marlo no game.
Reaction score
265
Ok, new version is up.

Thanks for reporting that bug. If you find more, report them too.
 

Viikuna

No Marlo no game.
Reaction score
265
Yep, this can be used in maps with 12 or less players.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top