System Rain

Jesus4Lyf

Good Idea™
Reaction score
397
Rain.

They say, "when it rains, it pours". I've heard of rain in America and England recently, quite heavy rain, too, apparently. Today it rained here where I am. For those who don't know, we've had an epic drought for a long time, and well, it still hasn't broken. But I went for walk in the rain, and as I watched it gather in streams on the road and in the gutters, I smiled and thought to myself...

Rain.

:thup:

I took a couple of "screenshots" for you all, too. I know some of you won't even bother to try this out. :)
rain1.jpg
rain2.jpg
rain3.jpg
rain4.jpg

Code:
JASS:
library Rain initializer OnInit
    globals
        private constant real INITIAL_HEIGHT=1100.
        private constant real FALL_SPEED=20. // Divided by 32.
        private constant real RUN_SPEED=.4 // Divided by 32, dependant on smoothing, also.
        private constant real SMOOTHING=74.
        private constant integer LIFESPAN_TICKS=400 // Max raindrops, also.
        // ====
        private boolean Raining=true
        // ====
        private real MinX
        private real MaxX
        private real MinY
        private real MaxY
    endglobals
    public function Start takes nothing returns nothing
        set Raining=true
    endfunction
    public function Stop takes nothing returns nothing
        set Raining=false
    endfunction
    
    struct raindrop
        unit u
        real x=GetRandomReal(MinX,MaxX)
        real y=GetRandomReal(MinY,MaxY)
        real z=INITIAL_HEIGHT // also z for falling
        
        integer index // For the very end, removing from "Running"...
    endstruct
    
    private function RainHandler takes nothing returns nothing
        //====================================================
        // A different way to code...
        //====================================================
        globals//locals
            private integer i
            private raindrop Current
        endglobals
        
        //====================================================
        globals
            private raindrop array Remove
            private integer tick=0
            private integer later=LIFESPAN_TICKS
        endglobals
        
        // "later" must be always LIFESPAN_TICKS ahead of tick.
        set tick=tick+1
        if tick>8190 then
            set tick=1
        endif
        set later=later+1
        if later>8190 then
            set later=1
        endif
        
        //====================================================
        globals
            private raindrop array Running
            private integer RunningMax=0
        endglobals
        
        //====================================================
        globals
            private raindrop array Falling
            private integer FallingMax=0
        endglobals
        
        //====================================================
        // Timeout the old drops.
        //====================================================
        //  How to time out a vast number of objects with O(1)
        //  compelxity... <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite1" alt=":)" title="Smile    :)" loading="lazy" data-shortname=":)" />
        set Current=Remove[tick]
        if Current!=0 then
            // When I first did this, this next line was missing.
            // Needless to say, if you understand the code, you
            // could guess it took me a little while to figure out.
            set Running[RunningMax].index=Current.index
            
            set Running[Current.index]=Running[RunningMax]
            set RunningMax=RunningMax-1
            
            call ShowUnit(Current.u,false)
            call UnitRemoveAbility(Current.u,&#039;Aloc&#039;)
            call Current.destroy()
            
            set Remove[tick]=0
        endif
        
        //====================================================
        // Creation.
        if Raining then
            // Create a raindrop.
            set FallingMax=FallingMax+1
            set Current=raindrop.create()
            set Falling[FallingMax]=Current
            
            set Remove[later]=Current // So very efficient...
            
            call ShowUnit(Current.u,true)
            call SetUnitPosition(Current.u,Current.x,Current.y)
            call UnitAddAbility(Current.u,&#039;Aloc&#039;)
            call SetUnitFlyHeight(Current.u,INITIAL_HEIGHT,0)
        endif
        
        //====================================================
        // Falling.
        set i=FallingMax
        loop
            exitwhen i==0
            set Current=Falling<i>
            set Current.z=Current.z-FALL_SPEED
            if Current.z&lt;0. then
                // ====
                set Falling<i>=Falling[FallingMax]
                set FallingMax=FallingMax-1
                
                call SetUnitFlyHeight(Current.u,0,0)
                
                set RunningMax=RunningMax+1
                set Running[RunningMax]=Current
                
                set Current.index=RunningMax // To remove from running.
                // ====
            else
                call SetUnitFlyHeight(Current.u,Current.z,0)
            endif
            
            set i=i-1
        endloop
        
        //====================================================
        // Running.
        globals
            private location l=Location(0,0)
            private real rainx // JassHelper error if renamed to x.
            private real rainy // JassHelper error if renamed to y.
            private real thisz
        endglobals
        
        set i=RunningMax
        loop
            exitwhen i==0
            set Current=Running<i>
            
            // Update velocities.
            set rainx=Current.x
            set rainy=Current.y
            call MoveLocation(l,rainx,rainy)
            set thisz=GetLocationZ(l)
            call MoveLocation(l,rainx+SMOOTHING,rainy)
            set Current.x=rainx+(thisz-GetLocationZ(l))*RUN_SPEED
            call MoveLocation(l,rainx,rainy+SMOOTHING)
            set Current.y=rainy+(thisz-GetLocationZ(l))*RUN_SPEED
            
            // Move raindrop.
            call SetUnitX(Current.u,Current.x)
            call SetUnitY(Current.u,Current.y)
            
            set i=i-1
        endloop
    endfunction
    
    private function OnInit takes nothing returns nothing
        local raindrop r=LIFESPAN_TICKS
        set MinX=GetCameraBoundMinX()
        set MaxX=GetCameraBoundMaxX()
        set MinY=GetCameraBoundMinY()
        set MaxY=GetCameraBoundMaxY()
        call TimerStart(CreateTimer(),0.03125,true,function RainHandler)
        loop
            exitwhen r==0
            set r.u=CreateUnit(Player(15),&#039;rain&#039;,MinY,MinX,0)
            call ShowUnit(r.u,false)
            set r=r-1
        endloop
    endfunction
endlibrary
</i></i></i>

In regards to real use... You probably want Bound Sentinel or a carefully created terrain, copy the dummy "Rain Drop" unit in the map as well as the code, and be warned that any terrain effects at runtime like shockwave and thunderclap will very likely desynch people.

Oh, and I enjoyed my walk very much. :)

PS.
If you think you have a good computer, see how high you can bump up "LIFESPAN_TICKS" and have the map run for at least a minute (if it can last that long, it should last forever probably). Tell us how high you got and what your fps was! (Use /fps in chat to find this out.) This can be some kinda test as to how well WC3 runs on your computer. And for anyone who previously thought moving 200 units around 32 times a second based on terrain was laggy... think twice, hey? :)

I've very tightly optimised this. =]
 

Attachments

  • Rain.w3x
    47.6 KB · Views: 566

wellwish3r

wishes wells.
Reaction score
52
wow now this is something original :thup:

i like, however i think it would only be useful in cinematics?
 

kingkingyyk3

Visitor (Welcome to the Jungle, Baby!)
Reaction score
216
I adjusted to 500, fps drops to 45.

I think dummies can be recycled..

Original :
JASS:
set Current.u=CreateUnit(Player(15),&#039;rain&#039;,Current.x,Current.y,0)

JASS:
call RemoveUnit(Current.u)


Recycle :
JASS:
if Current.u == null then
    set Current.u=CreateUnit(Player(15),&#039;rain&#039;,Current.x,Current.y,0)
else
    call ShowUnit(Current.u,true)
    call SetUnitPosition(Current.u,Current.x,Current.y)
endif

JASS:
    call ShowUnit(Current.u,false)
 

Jesus4Lyf

Good Idea™
Reaction score
397
i like, however i think it would only be useful in cinematics?
Pretty much. But I couldn't like... leave it in my maps folder and go "well I reckon that was epic, but no one shall ever know of it". I'm sure someone may find some use for it, even if its only to sit in their room occasionally and stare at the drops running down the streams... :thup: XD

I think dummies can be recycled..
And this would benefit... what? (I don't believe this would bring an efficiency increase, but I DO know that it would leave a few hundred dummy units sitting in the background if the Rain_Stop and Rain_Start functions were used. ;))

Well. I've gotten the same amount of +rep for this and AIDS so far... o.o -.-

Edit: More posts before I posted! :O
I tried 2000, and it kinda died after 40seconds or so
2000 takes 62 seconds to reach and stabilise. Try 1000. Should even work on your computer.

By the way, at 200 my computer runs on about 25 fps... lol :p

I'd love to see a screenshot of 1000... <3
 

kingkingyyk3

Visitor (Welcome to the Jungle, Baby!)
Reaction score
216
And this would benefit... what? (I don't believe this would bring an efficiency increase, but I DO know that it would leave a few hundred dummy units sitting in the background if the Rain_Stop and Rain_Start functions were used. )

In this case... You had to remove all dummies... T.T

Offtopic:)P) : Huh? Can the "pro" projectile system greatly reduce the length of code?

2000?!, Warcraft die after 35s with the value. FPS drops to 1.4 only. lol.

1000 raindrops :
rains.jpg
 

Jesus4Lyf

Good Idea™
Reaction score
397
Offtopic:)P) : Huh? Can the "pro" projectile system greatly reduce the length of code?
=/ You mean Gwypaas's? This probably wouldn't even run 200 with his.

Turns out it runs 400 smoothly on mine. There ya go. The screenies are only with 200. :)

Hmm. I could put recycling in. But I don't know that CreateUnit is really that much slower than ShowUnit and SetUnitPos. But I suppose it is probably worthwhile.

Disappointingly enough, the system's complexity seems to... unpredictably falter after a certain amount of time. Maybe recycling could fix this. Hmm. Unsure what that is. :)

>2000?!, Warcraft die after 35s with the value. FPS drops to 1.4 only. lol.
That means it only reached about 1100, and hasn't destroyed a single unit. :p
 
Reaction score
91
This is really awesome but I think it's a little laggy (from stable 64 fps to 57-61) but it's quite normal for such a big amount of moved units. I like it. :thup:
 

wellwish3r

wishes wells.
Reaction score
52
Well here is one at 1000 (ran perfectly fine):

Rain1.bmp

On a side note, i have to say that this was taken at all wc3 settings at mac with a resolution of 1920x1200, so if i went a little lower, i could maybe get to 2000 :p
 

wellwish3r

wishes wells.
Reaction score
52
Hawt.

I updated the code to preload all units, and then recycle them. It screwed with locust so I had to fix that too. :)

Runs epic smooth now. By the way, not sure that having more than 1000 units serves a point. Does it look any better to you changing from like... 600 to 1000? XD lol

to be honest, i saw now real different, except for maybe there bing more dummies running down the hills^^
 

kingkingyyk3

Visitor (Welcome to the Jungle, Baby!)
Reaction score
216
200 works good for me. No fps drops. 200 is sufficient and optimum, but not for beginner class graphic cards..

The new version.... My fps increased by 5 compared with old version.
 

wellwish3r

wishes wells.
Reaction score
52
Well i think this is a lot more awesome xD

Rain2.bmp

Btw: I can't see the updated version attached anywhere?

EDIT: Lol no its there >.>
 

Jesus4Lyf

Good Idea™
Reaction score
397
How about simulate other weather effects, like snow?
When I walk outside one day and see snow falling and gathering on fresh ground, maybe I'll be inspired to do that. :thup:

But it doesn't snow here.

And I don't usually speak in full caps but OMG THAT LOOKS AWESOME LOL.

PS. It didn't attach for some reason, but I did re-attach it. :p lol

Feel free to post your map for that fire one just for kicks, if you like... XD :)

Edit: Actually, I might do snow one day. But really it's just a case of removing the "running" in this and changing the projectile to frostwyrm breath... o.o
 

wellwish3r

wishes wells.
Reaction score
52
you know i just had an idea, how about making the raindrops get continuously smaller as they run down the terrain? Sort of like what real streams do when running a hill. Just an idea tho^^

EDIT: One comment for the snow: Make the dummies smaller, right now it looks like friggn comets rain from the sky (and then probably spawn them more frequently, since you have a lot less dummies on the map compared to rain.)
EDIT: Snow usually doesn't fall down straight, it sort of moves about randomly (like a falling paper)
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • Ghan Ghan:
    Howdy
  • Ghan Ghan:
    Still lurking
    +3
  • The Helper The Helper:
    I am great and it is fantastic to see you my friend!
    +1
  • The Helper The Helper:
    If you are new to the site please check out the Recipe and Food Forum https://www.thehelper.net/forums/recipes-and-food.220/
  • Monovertex Monovertex:
    How come you're so into recipes lately? Never saw this much interest in this topic in the old days of TH.net
  • Monovertex Monovertex:
    Hmm, how do I change my signature?
  • tom_mai78101 tom_mai78101:
    Signatures can be edit in your account profile. As for the old stuffs, I'm thinking it's because Blizzard is now under Microsoft, and because of Microsoft Xbox going the way it is, it's dreadful.
  • The Helper The Helper:
    I am not big on the recipes I am just promoting them - I use the site as a practice place promoting stuff
    +2
  • Monovertex Monovertex:
    @tom_mai78101 I must be blind. If I go on my profile I don't see any area to edit the signature; If I go to account details (settings) I don't see any signature area either.
  • The Helper The Helper:
    You can get there if you click the bell icon (alerts) and choose preferences from the bottom, signature will be in the menu on the left there https://www.thehelper.net/account/preferences
  • The Helper The Helper:
    I think I need to split the Sci/Tech news forum into 2 one for Science and one for Tech but I am hating all the moving of posts I would have to do
  • The Helper The Helper:
    What is up Old Mountain Shadow?
  • The Helper The Helper:
    Happy Thursday!
    +1
  • Varine Varine:
    Crazy how much 3d printing has come in the last few years. Sad that it's not as easily modifiable though
  • Varine Varine:
    I bought an Ender 3 during the pandemic and tinkered with it all the time. Just bought a Sovol, not as easy. I'm trying to make it use a different nozzle because I have a fuck ton of Volcanos, and they use what is basically a modified volcano that is just a smidge longer, and almost every part on this thing needs to be redone to make it work
  • Varine Varine:
    Luckily I have a 3d printer for that, I guess. But it's ridiculous. The regular volcanos are 21mm, these Sovol versions are about 23.5mm
  • Varine Varine:
    So, 2.5mm longer. But the thing that measures the bed is about 1.5mm above the nozzle, so if I swap it with a volcano then I'm 1mm behind it. So cool, new bracket to swap that, but THEN the fan shroud to direct air at the part is ALSO going to be .5mm to low, and so I need to redo that, but by doing that it is a little bit off where it should be blowing and it's throwing it at the heating block instead of the part, and fuck man
  • Varine Varine:
    I didn't realize they designed this entire thing to NOT be modded. I would have just got a fucking Bambu if I knew that, the whole point was I could fuck with this. And no one else makes shit for Sovol so I have to go through them, and they have... interesting pricing models. So I have a new extruder altogether that I'm taking apart and going to just design a whole new one to use my nozzles. Dumb design.
  • Varine Varine:
    Can't just buy a new heatblock, you need to get a whole hotend - so block, heater cartridge, thermistor, heatbreak, and nozzle. And they put this fucking paste in there so I can't take the thermistor or cartridge out with any ease, that's 30 dollars. Or you can get the whole extrudor with the direct driver AND that heatblock for like 50, but you still can't get any of it to come apart
  • Varine Varine:
    Partsbuilt has individual parts I found but they're expensive. I think I can get bits swapped around and make this work with generic shit though
  • Ghan Ghan:
    Heard Houston got hit pretty bad by storms last night. Hope all is well with TH.
  • The Helper The Helper:
    Power back on finally - all is good here no damage
    +1
  • V-SNES V-SNES:
    Happy Friday!
    +1

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top