Value controlled rain code - EDukeWiki

# Value controlled rain code

From EDukeWiki
Revision as of 12:14, 24 September 2006 by LordMisfit (talk | contribs)

This shows how to create a nice rain effect, allowing you to spawn and retain a certain amount of rain within a map. This works by creating both rain and a spawner for the rain. The "rain spawner" can then be given a hitag by the mapper, equal to the amount of rain they want to spawn. The rain itself spawns in a limited area, but "spreads out", allowing you to easily modify overall density.

First we will create the rain actor itself:

The following gamevars will be needed during the course of this code:

    gamevar TEMP 0 2
    gamevar RAND_DIST 0 2
    gamevar COUNT 0 2
    gamevar MHITAG 0 2
    gamevar ORIGRAINPOSX 0 2
    gamevar ORIGRAINPOSY 0 2

A couple of actor tile definitions are also required. Change these appropriately:

    define RSPAWN 3879
    define RAIN1 3890
    define RAINRIPPLE 3880

Here are our relevant move commands (remember, positive vertical values mean downward motion):

    move RAINDOWN 0 800
    move RAINSKY 800 0

And here are our actions, including a 5 frame splash:

    action INIT 0 1 1 1 1
    action RAINDROP 0 1 1 1 1
    action RAINSPLASH 1 5 1 1 5

And now on to the actual actor code:

    useractor notenemy RAIN1 0

    ifaction 0
    {
    	cstat 32768
    	action INIT
    	getactor[THISACTOR].x ORIGRAINPOSX
    	getactor[THISACTOR].y ORIGRAINPOSY
    }

You may have noticed we used "ifaction 0." This allows us to do things on what is basically actor intialization without wasting an action. Note that we saved the original x/y coordinates of the actor.

    sizeat 10 40

This sets the size of the sprite. In this case, I wanted it to be taller than it is wide. Adjust accordingly.

    ifaction INIT
    {
    	cstat 32768
    	ifoutside
    		nullop
    	else
    	{
    		setactor[THISACTOR].x ORIGRAINPOSX
    		setactor[THISACTOR].y ORIGRAINPOSY
    	}
    	move RAINSKY geth randomangle
    	ifrnd 96
    		action RAINDROP
    }
    else ifaction RAINDROP
    {
    	ifoutside
    		nullop
    	else
    	{
    		setactor[THISACTOR].x ORIGRAINPOSX
    		setactor[THISACTOR].y ORIGRAINPOSY
    	}

If the rain sprite goes indoors, it resets its position.

    	cstat 2
    	move 0 fall

Setting the sprite's cstat to 2 causes the sprite to be rendered with translucency level 1, "move 0" tells the actor not to execute any movement and "fall" simply tells the actor to move downward vertically until hitting the ground.

    	move RAINDOWN getv
    	iffloordistl 4
    	{
    		sizeat 20 20
    		action RAINSPLASH
    		move 0 fall
    	}
    }
    else ifaction RAINSPLASH
    {
    	sizeat 20 20

The sizeat command alters the size of the sprite. We're changing our sprite's size to account for it now being a "splash."

    	cstat 2
    	ifactioncount 5
    	{
    		cstat 32768
    		ifonwater
    			spawn RAINRIPPLE
    		getsector[THISACTOR].ceilingz TEMP
    		setactor[THISACTOR].z TEMP
    		action INIT
    	}
    }
    enda

The rain sprite is set up to spawn a ripple when it hits the water. Here's some quick code for that:

    action RIPPLING 0 9 1 1 4

    useractor notenemy RAINRIPPLE 0
    {
    	ifaction 0
    	{
    		sizeat 20 20
    		cstat 34
    		action RIPPLING
    		move 0 fall
    	}
    	ifactioncount 9
    		killit
    	iffloordistl 4 nullop
    	else killit
    }
    enda

Now comes the part where we make the rain spawner. First, we make a quick state to handle where the rain spawns:

    state spawnrain
    {
    	cstat 32768
    	ifvarvare MHITAG COUNT
    	{
    		setvar COUNT 0
    		killit
    	}
    	else
    	{
    		addvar COUNT 1
    		espawn RAIN1
    		getactor[THISACTOR].pal TEMP
    		setactor[RETURN].pal TEMP

    		ifrnd 64
    		{
    			getactor[RETURN].x TEMP
    			randvar RAND_DIST 2048
    			addvar RAND_DIST 2048
    			addvarvar TEMP RAND_DIST
    			setactor[RETURN].x TEMP
    		}
    		ifrnd 64
    		{
    			getactor[RETURN].x TEMP
    			randvar RAND_DIST -2048
    			subvar RAND_DIST 2048
    			addvarvar TEMP RAND_DIST
    			setactor[RETURN].x TEMP
    		}

    		ifrnd 64
    		{
    			getactor[RETURN].y TEMP
    			randvar RAND_DIST 2048
    			addvar RAND_DIST 2048
    			addvarvar TEMP RAND_DIST
    			setactor[RETURN].y TEMP
    		}
    		ifrnd 64
    		{
    			getactor[RETURN].y TEMP
    			randvar RAND_DIST -2048
    			subvar RAND_DIST 2048
    			addvarvar TEMP RAND_DIST
    			setactor[RETURN].y TEMP
    		}
    	}
    }
    ends

And the actor itself:

    action NORSPAWN 0 1 1 1 1
    useractor notenemy RSPAWN 0
    {
    	ifaction 0
    	{
    		getactor[THISACTOR].hitag MHITAG
    		setvar TEMP 0
    		setactor[THISACTOR].hitag TEMP
    		action NORSPAWN
    	}
    	state spawnrain
    }
    enda

The advantages of this method are quite obvious in that it lowers the amount of potential actors that will be in the map (the only time it would increase beyond what you defined is if the rain hits water, which should have a negligible effect) and makes it quite easy to edit the rain in a map. Also, rain is prevented from going indoors, except at the edges, limiting potential bugs, while providing a realistic effect.

Try it yourself.

Retrieved from "http://wiki.eduke32.com/w/index.php?title=Value_controlled_rain_code&oldid=5403"
Category:

- Tutorials