Dec0n's ZDooM Example Wad #1

Dec0n's ZDooM Example Wad #1
Look for more coming!
By Dec0nstructor
penfan@telerama.com
UIN: 12040401

Maximize for best viewing.
You may want to refer to my wad in an editor.
I am assuming you know the basics to scripting+wad editing.
There are four bugs non-serious bugs in my wad that I know of: the polyobj has some display probs, and the reactor does its thing repeatedly.
I'm a horrible tutorial maker :P

1. Complete Script

    #include "zcommon.acs"
    int jd;
    script 1 OPEN
    {
    	SetLineSpecial (1,80,8,0,1,0,0);
    	SetLineSpecial (2,80,8,0,2,0,0);
    	SetLineSpecial (3,80,8,0,3,0,0);
    	SetLineSpecial (4,80,8,0,4,0,0);
    	SetLineSpecial (5,80,10,0,0,0,0);
    	SetLineSpecial (6,80,12,0,0,0,0);
    	print (s:"this is dec0n's 1337 zdoom stuff wad thing");
    	delay (const:35*4);
    	print (s:"look around. if you want info on what something is or");
    	delay (const:35*4);
    	print (s:"how it twas done, hit a skull switch near the thing.");
    	delay (const:35*4);
    	print (s:"to get complete info on how all this was done, goto:");
    	delay (const:35*4);
    	print (s:"www.doomworld.com/wildman  For all your ZDooM needs *g*");
    	delay (const:35*4);
    	print (s:"Ignore the horrible map job, i just whipped this up quickly.");
    }
    script 2 (void)
    {
    	Door_Open (const:2, 32);
    	Light_Fade (const:1, 240, 32);
    	delay (const:300);
    	Door_Close (const:2, 32);
    	Light_Fade (const:1, 160, 32);
    }
    script 3 (void)
    {
    	print (s:"this is an effect that makes it looks as if the lite\n'rushes in' from outside.");
    	delay (const:35*4);
    	print (s:"done via a script which does Door_Open, Light_Fade, Door_Close, Light_Fade.");
    	delay (const:35*4);
    	print (s:"also, try this with fog or colored lighting.");
    }
    script 4 (void)
    {
    	if (jd==0) {
    		jd=1;
    	}
    	if (jd==3) {
    		PolyObj_Move (const:1,32,128,128);
    		jd=4;
    	}
    	if (jd==2) {
    		PolyObj_Move (const:1,32,0,32);
    		jd=3;
    	}
    	if (jd==1) {
    		PolyObj_Move (const:1,32,128,32);
        	jd=2;
    	}
    }
    script 5 (void)
    {
    	print (s:"i had *alot* of trouble with this polyobj,\n but somehow i got it working. :P");
    	delay (const:35*4);
    	print (s:"anyway, this is an example of a 'jammed door'");
     	delay (const:35*4);
    	print (s:"a variable called jd shows how many times the door has been used");
    	delay (const:35*4);
    	print (s:"using if statements, the door will move a different way each time\nand jd is increased.");
    	delay (const:35*4);
    	print (s:"until the door is in its final position.");
    }
    script 6 (void)
    {
    	int i;
    	Thing_Projectile (1,53,0,48,0);
    	delay (const:30);
    	while (i < 10) {
    		i++;
    		Thing_ProjectileGravity (1,130,0,64,0);
    		delay (const:30);
    	}
    	Thing_ProjectileGravity (1,22,0,48,0);
    }
    script 7 (void)
    {
    	print (s:"this is sort of a tube effect");
    	delay (const:35*4);
    	print (s:"it is done by Thing_ProjectileGravity + Thing_Projectile functions.");
    }
    int but1;
    int but2;
    int but3;
    int but4;
    script 8 (int but)
    {
    	if (but==1) {
    		if (but1==1) {
    			SetLineTexture (1,SIDE_FRONT,TEXTURE_MIDDLE,"SW1GRAY1");
    			but1=0;
    			SetLineSpecial (1,80,8,0,1,0,0);
    		}
    		else {
    			SetLineTexture (1,SIDE_FRONT,TEXTURE_MIDDLE,"SW2GRAY1");
    			but1=1;
    			SetLineSpecial (1,80,8,0,1,0,0);
    		}
    		if (but1==0 && but2==1 && but3==0 && but4==1) {
    			print (s:"Password accepted.")
    			Door_Open (const:3,32);
    			SetLineSpecial (1,0,0,0,0,0,0);
    			SetLineSpecial (2,0,0,0,0,0,0);
    			SetLineSpecial (3,0,0,0,0,0,0);
    			SetLineSpecial (4,0,0,0,0,0,0);
    		}
    		terminate;
    	}
    	if (but==2) {
    		if (but2==1) {
    			SetLineTexture (2,SIDE_FRONT,TEXTURE_MIDDLE,"SW1GRAY1");
    			but2=0;
    			SetLineSpecial (2,80,8,0,2,0,0);
    		}
    		else {
    			SetLineTexture (2,SIDE_FRONT,TEXTURE_MIDDLE,"SW2GRAY1");
    			but2=1;
    			SetLineSpecial (2,80,8,0,2,0,0);
    		}
    		if (but1==0 && but2==1 && but3==0 && but4==1) {
    			print (s:"Password accepted.")
    			Door_Open (const:3,32);
    			SetLineSpecial (1,0,0,0,0,0,0);
    			SetLineSpecial (2,0,0,0,0,0,0);
    			SetLineSpecial (3,0,0,0,0,0,0);
    			SetLineSpecial (4,0,0,0,0,0,0);
    		}
    		terminate;
    	}
    	if (but==3) {
    		if (but3==1) {
    			SetLineTexture (3,SIDE_FRONT,TEXTURE_MIDDLE,"SW1GRAY1");
    			but3=0;
    			SetLineSpecial (3,80,8,0,3,0,0);
    		}
    		else {
    			SetLineTexture (3,SIDE_FRONT,TEXTURE_MIDDLE,"SW2GRAY1");
    			but3=1;
    			SetLineSpecial (3,80,8,0,3,0,0);
    		}
    		if (but1==0 && but2==1 && but3==0 && but4==1) {
    			print (s:"Password accepted.")
    			Door_Open (const:3,32);
    			SetLineSpecial (1,0,0,0,0,0,0);
    			SetLineSpecial (2,0,0,0,0,0,0);
    			SetLineSpecial (3,0,0,0,0,0,0);
    			SetLineSpecial (4,0,0,0,0,0,0);
    		}
    		terminate;
    	}
    	else {
    		if (but4==1) {
    			SetLineTexture (4,SIDE_FRONT,TEXTURE_MIDDLE,"SW1GRAY1");
    			but4=0;
    			SetLineSpecial (4,80,8,0,4,0,0);
    		}
    		else {
    			SetLineTexture (4,SIDE_FRONT,TEXTURE_MIDDLE,"SW2GRAY1");
    			but4=1;
    			SetLineSpecial (4,80,8,0,4,0,0);
    		}
    		if (but1==0 && but2==1 && but3==0 && but4==1) {
    			print (s:"Password accepted.")
    			Door_Open (const:3,32);
    			SetLineSpecial (1,0,0,0,0,0,0);
    			SetLineSpecial (2,0,0,0,0,0,0);
    			SetLineSpecial (3,0,0,0,0,0,0);
    			SetLineSpecial (4,0,0,0,0,0,0);
    		}
    	}
    }
    script 9 (void)
    {
    	print (s:"this is a complicated script which does a 'password' effect.");
    	delay (const:4*35);
    	print (s:"hit the buttons until you get the right combination,\nand the door shall open.");
    	delay (const:4*35);
    	print (s:"done via setlinespecial and setlinetexture fuctions,");
    	delay (const:4*35);
    	print (s:"the script checks to see if the right combination of buttons are on.");
    	delay (const:4*35);
    	print (s:"then it opens the door.");
    }
    script 10 (void)
    {
    	Thing_Projectile (2,127,128,105,0);
    	delay (const:15);
    	SetLineTexture (5,SIDE_FRONT,TEXTURE_BOTTOM,"SW1EXIT");
    	SetLineSpecial (5,80,10,0,0,0,0);
    }
    script 11 (void)
    {
    	print (s:"this is a turret effect. done via the thing_projectile function");
    	delay (const:4*35);
    	print (s:"a delay takes place after a rocket is shot so the player cant");
    	delay (const:4*35);
    	print (s:"make a line of death :P");
    	delay (const:4*35);
    	print (s:"also, with additional scripting, you can do these:");
    	delay (const:4*35);
    	print (s:"make it shoot different projectiles,");
    	delay (const:4*35);
    	print (s:"make it have limited ammo,");
    	delay (const:4*35);
    	print (s:"make it not work after it has been shot.");
    }
    script 12 (void) {
    	DamageThing (255);
    	DamageThing (255);
    	print (s:"didn't your mom ever tell you not go through red lasers?")
    }
    script 13 (void) {
    	SetLineSpecial (6,0,0,0,0,0,0);
    	SetLineTexture (6,SIDE_FRONT,TEXTURE_MIDDLE,"-");
    	SetLineTexture (6,SIDE_BACK,TEXTURE_MIDDLE,"-");
    }
    script 14 (void) {
    	print (s:"this is a force field effect.\ntexture is from teamtnt's reclaimation. thx!");
    	delay (const:35*4);
    	print (s:"the texture is made translucent by a unused line with a TranslucentLine\n special.");
    	delay (const:35*4);
    	print (s:"then, using setlinespecial, the lasers are set to run a script");
    	delay (const:35*4);
    	print (s:"which does damagething when the player crosses.");
    	delay (const:35*4);
    	print (s:"the swicth is set to launch a script");
    	delay (const:35*4);
    	print (s:"which erases the line's texture and special.");
    }
    script 15 (void) {
    	print (s:"shoot the reactor!")
    }
    script 16 (void) {
    	int i;
    	Thing_Destroy (12);
    	while ( i < 11 ) {
    		i++;
    		Thing_Projectile (4,126,128,120,0);
    		Thing_Projectile (5,126,160,120,0);
    		Thing_Projectile (4,126,192,120,0);
    		Thing_Projectile (4,126,224,120,0);
    		Thing_Projectile (4,126,0,120,0);
    		Thing_Projectile (4,126,32,120,0);
    		Thing_Projectile (4,126,64,120,0);
    		Thing_Projectile (4,126,96,120,0);
    	}
    	Radius_Quake (9,35*5,1,15,14);
    	Floor_LowerToLowest (13,64);
    	delay (const:35*11);
    	print (s:"\cGthanks for playing! things to look for in my next example wad:");
    	delay (const:35*4);
    	print (s:"\cHslot machine, \cIhealing station, \cFbreakable glass, \cD'detonation countdown',\n\cAand more!");
    	delay (const:35*4);
    	print (s:"\cDThanks to:");
    	delay (const:35*4);
    	print (s:"teamtnt, for many hours of dm with reclaimation, and i use one\nof their textures :)");
    	delay (const:35*4);
    	print (s:"Rick Clark a.k.a. Wildman, for his ZDooM tutorials, which helped me\nand others alot.");
    	delay (const:35*4);
    	print (s:"Randy Heit, for the great source port ZDooM and the ZDooM editing faq.");
    	delay (const:35*4);
    	print (s:"well, there isn't really any exit, so you have to quit :P");
    }
    script 17 (void) {
    	print (s:"this is a simple reactor effect. when the 'reactor' is shot,");
    	delay (const:35*4);
    	print (s:"a script is launched which does a Thing_Destroy on the");
    	delay (const:35*4);
    	print (s:"cyberdemons, does a radius_quake, and lowers the reactor.");
    }

2. The Beginning

Script 1 controls the start-up functions:

    script 1 OPEN
    {
    	SetLineSpecial (1,80,8,0,1,0,0);
    	SetLineSpecial (2,80,8,0,2,0,0);
    	SetLineSpecial (3,80,8,0,3,0,0);
    	SetLineSpecial (4,80,8,0,4,0,0);
    	SetLineSpecial (5,80,10,0,0,0,0);
    	SetLineSpecial (6,208,6,56,0,0,0);
    	SetLineSpecial (6,80,12,0,0,0,0);
    	print (s:"this is dec0n's 1337 zdoom stuff wad thing");
    	delay (const:35*4);
    	print (s:"look around. if you want info on what something is or");
    	delay (const:35*4);
    	print (s:"how it twas done, hit a skull switch near the thing.");
    	delay (const:35*4);
    	print (s:"to get complete info on how all this was done, goto:");
    	delay (const:35*4);
    	print (s:"www.doomworld.com/wildman  For all your ZDooM needs *g*");
    	delay (const:35*4);
    	print (s:"Ignore the horrible map job, i just whipped this up quickly.");
    }

Since this is an OPEN script, it automatically starts at the beginning of the map.

- SetLineSpecial - These will be discussed later in the tutorial
- print - Prints some centered text on the screen
- delay - Causes the script to wait that number of tics before proceeding with the next command. A tic is 1/35 of a second, therefore 35 tics = 1 second. I.E. the 35*4 = 4 seconds.

That was easy, now to get on the harder things.

2. The 'Info' Scripts

If you tried my wad, you should know the info skulls, that explain about an effect when used. These are pretty much like script 1:

    script 3 (void)
    {
    	print (s:"this is an effect that makes it looks as if the lite\n'rushes in' from outside.");
    	delay (const:35*4);
    	print (s:"done via a script which does Door_Open, Light_Fade, Door_Close, Light_Fade.");
    	delay (const:35*4);
    	print (s:"also, try this with fog or colored lighting.");
    }

Hence, you already know the print and delay commands. The \n starts a new line, so the first message appears like this:

              this is an effect which makes it looks as if the lite
                           'rushes in' from outside.

The backslash (\) has a special meaning, so if you want to print a backslash, you have to put a \\ instead of a \.

Any other scripts above I do not explain are info scripts, and are the same thing, except for different messages.

3. The 'Light_Fade' Effect

This script makes it looks like the light from the outside sector lights up the inside darker sector.

    script 2 (void)
    {
    	Door_Open (const:2, 32);
    	Light_Fade (const:1, 240, 32);
    	delay (const:300);
    	Door_Close (const:2, 32);
    	Light_Fade (const:1, 160, 32);
    }

Here are some new functions:

- Door_Open ( tag of affected sector, how fast to open ) - Opens the tagged door (Duh)
- Light_Fade ( tag of affected sector, light level to change to, speed to fade ) - 'Fades' the light level of the tagged sector to the specified value.
- Door_Close ( tag of affected sector, how fast to close ) - Same as Door_Open, but closes the door.

The door sector has the tag of 1, and the inside sector (the one which will have the affected light) has a tag of 2. The door's linedef's are tagged to do ACS_Execute:

ACS_Execute ( script#, map#, Argument, Argument, Argument ) - Launches the specified script. If the map# is 0, the script is on the specified map. If it is on a different map, the script will not take place until the player enters the map. The Arguments are used inside the script (they will be used later).

So we do an ACS_Execute on script 2, which launches the script, opens the door, brightens the sector, waits 300 tics, closes the door, and darkens the sector.

You can also do this with colored lighting/fog:

Door_Open (const:blah, blah);
Sector_SetColor (1,200,255,255);
Sector_SetColor (1,150,255,255);
Sector_SetColor (1,100,255,255);
delay (const: blah);
Door_Close (const:blah, blah);
Sector_SetColor (1,150,255,255)
Sector_SetColor (1,200,255,255)
Sector_SetColor (1,255,255,255)

4. The 'Jammed Door' Effect

This creates the effect of a 'jammed door'

    int jd;

    script 4 (void)
    {
    	if (jd==0) {
    		jd=1;
    	}
    	if (jd==3) {
    		PolyObj_Move (const:1,32,128,128);
    		jd=4;
    	}
    	if (jd==2) {
    		PolyObj_Move (const:1,32,0,32);
    		jd=3;
    	}
    	if (jd==1) {
    		PolyObj_Move (const:1,32,128,32);
     		jd=2;
    	}
    }

At the top of the all the scripts, you will see int jd; This creates a variable which we use in this script. Notice that it is not inside a script, that makes it map-scope, meaning it affects all scripts in the map. If I were to put it inside the script, it would only affect that script, and would be erased when the script ended. When you first declare the variable, it is automatically assigned the value of nothing. The PolyObj's linedefs are assigned to ACS_Execute script 4. In the script, the if statement is used to check if jd is a certain number; Notice that to check for equality you have to use ==, not = At first, the script will find that jd is 0, and run the code, which sets jd to 1. The script doesn't stop after that, so it runs the rest of the script. Since jd isn't 2 or 3, it doesn't run the commands there. But it does run the last if, since jd = 1.

And does the PolyObj_Move command:

PolyObj_Move ( polyobject#, speed at which to move polyobj, angle at which to move polyobj, distance to move )

For info on setting up PolyObjs, look at Wildman's PolyObj tutorials.

Anyway, the PolyObj will move 32 units to the west, (128 = west) not enough to let the player through. jd is increased.

Note: You can also increase a variable by adding ++ to it, I.E. jd++;

Then when the player uses the door again, it will run the jd==2 if because we increased jd. This does the same thing except the PolyObj is moved back to its original position. (Moving 32 units east 0 = east) The last time the door is opened fully (Moving 128 units west) and jd is increased to 4, and since there is no command for 4, nothing will happen the next time around. (Pretty self-explanatory, heh)

You can also add more ways for the door to move.

5. 'Tube' Effect

This produces the 'tube' effect seen in my wad:

    script 6 (void)
    {
    	int i;
    	Thing_Projectile (1,53,0,48,0);
    	delay (const:30);
    	while (i < 10) {
    		i++;
    		Thing_ProjectileGravity (1,130,0,64,0);
    		delay (const:30);
    	}
    	Thing_ProjectileGravity (1,22,0,48,0);
    }

First off, a map spot is placed inside the tube, and it is given a thing id of 1. This is where the things will spawn. Then, the variable i is declared. A Thing_Projectile function is called which spawns a Revenant Fireball:

Thing_Projectile ( thing id of mapspot, type# of thing to spawn, angle at which to fire, speed, vertical speed )

Thing #53 = Rev. FireBall

For info on what the # of a thing is, look at the Spawnable Things section in the ZDooM reference.

Then, a 30 tic delay takes place. A while statement will continue to do the commands inside it until it is not true. So, this while statement will continue to run the commands until i is equal to 10. Inside the while, you notice that i is increased, (i++;) and a Thing_ProjectileGravity is run. (Thing_ProjectileGravity is the same as Thing_Projectile except that the thing it spawns will be affected by gravity.) Thing #130 = Blood. Heh heh. :) This is done 10 times, and then last, an armor bonus is spawned. (Thing #22 = Armor Bonus.)

6. 'Password' Effect

This is where it gets pretttty complicated. :P

    script 8 (int but)
    {
    	if (but==1) {
    		if (but1==1) {
    			SetLineTexture (1,SIDE_FRONT,TEXTURE_MIDDLE,"SW1GRAY1");
    			but1=0;
    			SetLineSpecial (1,80,8,0,1,0,0);
    		}
    		else {
    			SetLineTexture (1,SIDE_FRONT,TEXTURE_MIDDLE,"SW2GRAY1");
    			but1=1;
    			SetLineSpecial (1,80,8,0,1,0,0);
    		}
    		if (but1==0 && but2==1 && but3==0 && but4==1) {
    			print (s:"Password accepted.")
    			Door_Open (const:3,32);
    			SetLineSpecial (1,0,0,0,0,0,0);
    			SetLineSpecial (2,0,0,0,0,0,0);
    			SetLineSpecial (3,0,0,0,0,0,0);
    			SetLineSpecial (4,0,0,0,0,0,0);
    		}
    		terminate;
    	}
    	if (but==2) {
    		if (but2==1) {
    			SetLineTexture (2,SIDE_FRONT,TEXTURE_MIDDLE,"SW1GRAY1");
    			but2=0;
    			SetLineSpecial (2,80,8,0,2,0,0);
    		}
    		else {
    			SetLineTexture (2,SIDE_FRONT,TEXTURE_MIDDLE,"SW2GRAY1");
    			but2=1;
    			SetLineSpecial (2,80,8,0,2,0,0);
    		}
    		if (but1==0 && but2==1 && but3==0 && but4==1) {
    			print (s:"Password accepted.")
    			Door_Open (const:3,32);
    			SetLineSpecial (1,0,0,0,0,0,0);
    			SetLineSpecial (2,0,0,0,0,0,0);
    			SetLineSpecial (3,0,0,0,0,0,0);
    			SetLineSpecial (4,0,0,0,0,0,0);
    		}
    		terminate;
    	}
    	if (but==3) {
    		if (but3==1) {
    			SetLineTexture (3,SIDE_FRONT,TEXTURE_MIDDLE,"SW1GRAY1");
    			but3=0;
    			SetLineSpecial (3,80,8,0,3,0,0);
    		}
    		else {
    			SetLineTexture (3,SIDE_FRONT,TEXTURE_MIDDLE,"SW2GRAY1");
    			but3=1;
    			SetLineSpecial (3,80,8,0,3,0,0);
    		}
    		if (but1==0 && but2==1 && but3==0 && but4==1) {
    			print (s:"Password accepted.")
    			Door_Open (const:3,32);
    			SetLineSpecial (1,0,0,0,0,0,0);
    			SetLineSpecial (2,0,0,0,0,0,0);
    			SetLineSpecial (3,0,0,0,0,0,0);
    			SetLineSpecial (4,0,0,0,0,0,0);
    		}
    		terminate;
    	}
    	else {
    		if (but4==1) {
    			SetLineTexture (4,SIDE_FRONT,TEXTURE_MIDDLE,"SW1GRAY1");
    			but4=0;
    			SetLineSpecial (4,80,8,0,4,0,0);
    		}
    		else {
    			SetLineTexture (4,SIDE_FRONT,TEXTURE_MIDDLE,"SW2GRAY1");
    			but4=1;
    			SetLineSpecial (4,80,8,0,4,0,0);
    		}
    		if (but1==0 && but2==1 && but3==0 && but4==1) {
    			print (s:"Password accepted.")
    			Door_Open (const:3,32);
    			SetLineSpecial (1,0,0,0,0,0,0);
    			SetLineSpecial (2,0,0,0,0,0,0);
    			SetLineSpecial (3,0,0,0,0,0,0);
    			SetLineSpecial (4,0,0,0,0,0,0);
    		}
    	}
    }

Whoa. heh. Well, if you notice, each of the password button's special is set to Line_SetIdentification. This sort of gives the line a number. and if you notice they are set to 1, 2, 3, and 4 respectively. To change a lines texture, which we will have to do, the line requires a ID. Line_SetIdentification automatically takes place, so there is no need to set something to activate it.

In the password effect, I needed the switches to stay on & off when flicked, while still being able to be used repetitively. But if I set the switch to do it's thing repeatedly, the switch will switch back to it's of texture. So I had to make it not repetitive and get pretty complicated.

Anyway, remember those SetLineSpecial's at the beginning of the scripts? Now we use the first four:

SetLineSpecial (1,80,8,0,1,0,0);
SetLineSpecial (2,80,8,0,2,0,0);
SetLineSpecial (3,80,8,0,3,0,0);
SetLineSpecial (4,80,8,0,4,0,0);

Since the Line_SetIdentification takes up the lines special, we have no place to set it to run the script we need! But we can set the line's special in a script, and it will still retain it's lineID.

SetLineSpecial ( lineID#, function#, functionArgument, functionArgument, functionArgument, functionArgument, functionArgument )

Function# 80 is ACS_Execute. The function Arg's are the parameters for the function, so in this case it would run script 8 on this map, with a script argument of 1. For info on what the function#'s are look in the Zdoom reference under Action Specials.

Anyway, I said before I would get into script arguments, and now I shall. If you notice, in the SetLineSpecial above, this script will be launched with 1 argument. This argument is either 1, 2, 3, or 4, and it tells the script which button was used.

      script 8 (int but)

This is all you have to do to use the script argument. Declare a variable for it to be stored at, and it shall be there. :)

    	if (but==1) {
    		if (but1==1) {
    			SetLineTexture (1,SIDE_FRONT,TEXTURE_MIDDLE,"SW1GRAY1");
    			but1=0;
    			SetLineSpecial (1,80,8,0,1,0,0);
    		}
    		else {
    			SetLineTexture (1,SIDE_FRONT,TEXTURE_MIDDLE,"SW2GRAY1");
    			but1=1;
    			SetLineSpecial (1,80,8,0,1,0,0);
    		}
    		if (but1==0 && but2==1 && but3==0 && but4==1) {
    			print (s:"Password accepted.")
    			Door_Open (const:3,32);
    			SetLineSpecial (1,0,0,0,0,0,0);
    			SetLineSpecial (2,0,0,0,0,0,0);
    			SetLineSpecial (3,0,0,0,0,0,0);
    			SetLineSpecial (4,0,0,0,0,0,0);
    		}
    		terminate;
    	}

OK, here is the complicated part. Now, the script checks to see if but (Our script arg) is 1. If it is, then the player has used the first button. Then it check to see if it is on (if but1=1). If it is, change it's texture with SetLineTexture:

SetLineTexture ( lineID#, linedefSide, texture_top texture_middle texture_bottom, texture to change to )

So we will set line #1's (the 1st button's) middle texture to the normal off texture ("SW1GRAY1"). Then, but1 is set to 0, to show that the 1st button is off. To make it so the switch can be used again (remember, our buttons are NOT repeatable) we reset the line's special. This makes the engine think that the line hasn't been used, so we can use it again.

The else statement is used after an if statement. The commands inside an else will run only if the if statement before it was not true. This means if our button is off (but1=0) it will run these commands. The commands here are the same as the ones in the if statement except that we set but1=1 to show that the button is now on, and the texture is set to SW2GRAY1, the on texture.

The if (but1==0 && but2==1 && but3==0 && but4==1) translates into if button 1 is off, and if button 2 is on, and if button 3 is off, and if button 4 is on, run these things. (Because the password is correct.) The commands inside open the door, print Password Accepted, and set the button's special to do nothing, so the buttons cannot be played with after the door has been opened.

terminate just stops the script, so that the other commands below it are not run.

The code for the other buttons is pretty much the same, except the number of the switch will be different. (I.E. but1 is but2 for switch2)

Whew, the hardest thing is done. ;)

7. 'Turret' Effect

This is actually pretty easy:

    script 10 (void)
    {
    	Thing_Projectile (2,127,128,105,0);
    	delay (const:15);
    	SetLineTexture (5,SIDE_FRONT,TEXTURE_BOTTOM,"SW1EXIT");
    	SetLineSpecial (5,80,10,0,0,0,0);
    }

The line that you want to use to activate the turret is set to Line_SetIdentification and it should be non repeatable, and in this case the lineid is 5. At the top of the scripts, this is used:

    	SetLineSpecial (5,80,10,0,0,0,0);

This sets the line to run the script.

First, a map spot with a thing id of 2 was put on the end of my badly constructed turret, with a Z of about 40 or so. Then, a rocket is spawned (thing# 127) at the map point when the player activates the line. Then a delay of about 15 tics (My guess to how long a rocket takes to reload) before the texture is set back to the off texture and it being able to be done again. (The SetLineSpecial resets the line.) I'm prolly gonna use this in my teamplay mod.

8. 'Force Field' Effect

Here is the laser force field effect:

    script 12 (void) {
    	DamageThing (255);
    	DamageThing (255);
    	print (s:"didn't your mom ever tell you not go through red lasers?")
    }
    script 13 (void) {
    	SetLineSpecial (6,0,0,0,0,0,0);
    	SetLineTexture (6,SIDE_FRONT,TEXTURE_MIDDLE,"-");
    	SetLineTexture (6,SIDE_BACK,TEXTURE_MIDDLE,"-");
    }

To be able to change the line's texture, we need to give it a lineID, in this case, it is 6. And now we need it to run script 12, so it will hurt the player when he walks through, like this:

    SetLineSpecial (6,80,12,0,0,0,0);

Then, we need to set the line to be Translucent. We do this by setting a different line's special to Translucentline. I used a line in the unused sector that held the jammed door polyobj:

TranslucentLine (lineID#, amount of opacity(0-255))

Mine was:

TranslucentLine (6, 156)

TranslucentLine automatically does its thing when the map starts, like Line_SetIdentification.

Now to look over script 12:

    script 12 (void) {
    	DamageThing (255);
    	DamageThing (255);
    	print (s:"didn't your mom ever tell you not go through red lasers?")
    }

This does DamageThing on the player when he crosses the line. We do it twice because a player with MegaSphere will not be dead when hit with only 255 damage.

DamageThing (amount of damage)

Then it prints the message.

I set a switch to run script 13.

    script 13 (void) {
    	SetLineSpecial (6,0,0,0,0,0,0);
    	SetLineTexture (6,SIDE_FRONT,TEXTURE_MIDDLE,"-");
    	SetLineTexture (6,SIDE_BACK,TEXTURE_MIDDLE,"-");
    }

This makes the line's back and front textures to none ("-") and sets the line to do nothing (SetLineSpecial 0) So the player will not die anymore.

9. 'Reactor' Effect

First, we have a line to say 'Shoot the reactor!' when the player crosses so he doesn't sit their befuddled of what to do when toe to toe with 5 cyberdemons :P

    script 15 (void) {
    	print (s:"shoot the reactor!")
    }

      Then, the long script for when the reactor is shot:
    script 16 (void) {
    	int i;
    	Thing_Destroy (12);
    	while ( i < 11 ) {
    		i++;
    		Thing_Projectile (4,126,128,120,0);
    		Thing_Projectile (5,126,160,120,0);
    		Thing_Projectile (6,126,192,120,0);
    		Thing_Projectile (7,126,224,120,0);
    		Thing_Projectile (8,126,0,120,0);
    		Thing_Projectile (9,126,32,120,0);
    		Thing_Projectile (10,126,64,120,0);
    		Thing_Projectile (11,126,96,120,0);
    	}
    	Radius_Quake (9,35*5,1,15,14);
    	Floor_LowerToLowest (13,64);
    	delay (const:35*11);
    	print (s:"\cGthanks for playing! things to look for in my next example wad:");
    	delay (const:35*4);
    	print (s:"\cHslot machine, \cIhealing station, \cFbreakable glass, \cD'detonation countdown',\n\cAand more!");
    	delay (const:35*4);
    	print (s:"\cDThanks to:");
    	delay (const:35*4);
    	print (s:"teamtnt, for many hours of dm with reclaimation, and i use one\nof their textures :)");
    	delay (const:35*4);
    	print (s:"Rick Clark a.k.a. Wildman, for his ZDooM tutorials, which helped me\nand others alot.");
    	delay (const:35*4);
    	print (s:"Randy Heit, for the great source port ZDooM and the ZDooM editing faq.");
    	delay (const:35*4);
    	print (s:"well, there isn't really any exit, so you have to quit :P");
    }

Well, first we declare i, then we destroy all the cyberdemons with Thing_Destroy:

Thing_Destroy (thingid);

All the cyberdemons are all tagged with 12. Map spots are put around the reactor (which in this case are tagged 4-11) Then, while is used to spawn Cacodemon fireballs (Thing# 126) to add to the effect. An earthquake then takes place via a Radius_Quake:

Radius_Quake ( intensity of quake, length of quake in tics, Radius of damage in 64x64 units, radius of tremor in 64x64 units, thing id in which the center of quake shall be );

In this case, the quake is centered at a map spot with the thing id of 14. Then, a Floor_LowerToLowest is called, Which lowers the tagged sector (which is the reactor) to the lowest neighboring floor:

Floor_LowerToLowest ( Sector to lower, speed at which to lower );

Then we print the ending. But ho, we have one last thing. \c changes the color of the text. The letter after \c shows what color it will be:

        A		Brick
        B		Tan
        C		Grey/White
        D		Green
        E		Brown
        F		Gold
        G		Red
        H		Blue
        I		Orange
        -		The user's preferred color
        +		A color guaranteed to be different from -

10. Other Resources

http://www.doomworld.com/wildman/ ZDoom Technical Reference, Zdoom tutorials galore :)

http://zdoom.notgod.com Zdoom homepage

Submitted by Dec0nstructor .

Back