# System Rain

Discussion in 'Systems and Snippets' started by Jesus4Lyf, Jun 30, 2009.

1. ### Jesus4LyfGood Idea™

Ratings:
+394 / 0 / -0
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.

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... :)
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,'Aloc')
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 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<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),'rain',MinY,MinX,0)
call ShowUnit(r.u,false)
set r=r-1
endloop
endfunction
endlibrary``````
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. =]

File size:
47.6 KB
Views:
353
• Like x 3
2. ### wellwish3rwishes wells.

Ratings:
+52 / 0 / -0
wow now this is something original :thup:

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

3. ### kingkingyyk3Visitor (Welcome to the Jungle, Baby!)

Ratings:
+216 / 0 / -0
I adjusted to 500, fps drops to 45.

I think dummies can be recycled..

Original :
JASS:
``set Current.u=CreateUnit(Player(15),'rain',Current.x,Current.y,0)``

JASS:
``call RemoveUnit(Current.u)``

Recycle :
JASS:
``````if Current.u == null then
set Current.u=CreateUnit(Player(15),'rain',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)``

4. ### wellwish3rwishes wells.

Ratings:
+52 / 0 / -0
I tried 2000, and it kinda died after 40seconds or so

5. ### Jesus4LyfGood Idea™

Ratings:
+394 / 0 / -0
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

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 -.-

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

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

6. ### kingkingyyk3Visitor (Welcome to the Jungle, Baby!)

Ratings:
+216 / 0 / -0
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

OfftopicP) : 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 :

7. ### Jesus4LyfGood Idea™

Ratings:
+394 / 0 / -0
=/ 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.

8. ### Tyrande_ma3x.

Ratings:
+91 / 0 / -0
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:

9. ### wellwish3rwishes wells.

Ratings:
+52 / 0 / -0
Well here is one at 1000 (ran perfectly fine):

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

10. ### Jesus4LyfGood Idea™

Ratings:
+394 / 0 / -0
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

11. ### wellwish3rwishes wells.

Ratings:
+52 / 0 / -0
to be honest, i saw now real different, except for maybe there bing more dummies running down the hills^^

12. ### kingkingyyk3Visitor (Welcome to the Jungle, Baby!)

Ratings:
+216 / 0 / -0
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.

13. ### Jesus4LyfGood Idea™

Ratings:
+394 / 0 / -0
>maybe there bing more dummies running down the hills^^
Shouldn't be. It only changes the lifespan!

I agree that 200 is fine.

Cooool.

I might make a chill-out-at-2-am type map with this and some first person stuff on it. Hmm. Maybe, maybe... =]

14. ### kingkingyyk3Visitor (Welcome to the Jungle, Baby!)

Ratings:
+216 / 0 / -0
How about simulate other weather effects, like snow?

15. ### wellwish3rwishes wells.

Ratings:
+52 / 0 / -0
Well i think this is a lot more awesome xD

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

EDIT: Lol no its there >.>

16. ### Jesus4LyfGood Idea™

Ratings:
+394 / 0 / -0
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. 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

17. ### wellwish3rwishes wells.

Ratings:
+52 / 0 / -0
sure, but in the end it was just a replace tiles+trees and some random fire thrown in

File size:
47.3 KB
Views:
169
• Like x 1
18. ### Jesus4LyfGood Idea™

Ratings:
+394 / 0 / -0
Psh, I know that! Still cool though...

Updated the first post by removing my debug messages, lol. :thup:

Edit: Did someone say... snow? XD
*Shrugs* lol kinda works.

File size:
52.6 KB
Views:
172
19. ### wellwish3rwishes wells.

Ratings:
+52 / 0 / -0
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)

20. ### Jesus4LyfGood Idea™

Ratings:
+394 / 0 / -0
Hmm. Streams actually get -larger- as they go, usually, I think... XD

In regards to snow... meh. It was just for kicks.