=================================
The Duke Nukem 3D Con Editing FAQ
Version 3.1

Written by Joris B. Weimar
Updated by Jonah Bishop

Visit Map FAQ Central Today!
http://mapfaq.3dportal.com
=================================

TABLE OF CONTENTS

Note: Sections with a * in the table of contents denote a section of the FAQ that has been updated or added.

--------------------------
SECTION 1: FAQ INFORMATION
--------------------------
   1.1 About the Authors and General Information
   1.2 Where did the author get the information?
*  1.3 Revision History
*  1.4 Credits and Contributors

------------------------------
SECTION 2: CON BUILDING BLOCKS
------------------------------

   2.1 What is a state?
   2.2 What is an action?
   2.3 What is an ai?
   2.4 What is an actor?
   2.5 What is a useractor?
   2.6 What is an if construction?
*  2.7 The Complete Primitive List
   2.8 Predefined State Functions
   2.9 Known .CON bugs
   2.10 Things You Cannot Change

-----------------------
SECTION 3: LEGAL VALUES
-----------------------
   3.1 Values for addammo
   3.2 Values for addinventory and ifpinventory
   3.3 Values for addweapon
   3.4 Values for cstat and cstator
   3.5 Values for guts
   3.6 Values for ifp
   3.7 Values for ifwasweapon and shoot
   3.8 Values for spritepal

-------------------
SECTION 4: EXAMPLES
-------------------

   4.1 Example 1: Increase Duke Nukem's Health
   4.2 Example 2: Rubber Trash Cans Spawn Health When Destroyed
   4.3 Example 3: Booby-trapped Ammunition
   4.4 Example 4: Break the "Unbreakable" Plate (Versions 1.4/1.5 Only)
   4.5 Example 5: Make Duke eat some food (Versions 1.4/1.5 only)

---------------------------------
SECTION 5: A GENERAL CON OVERVIEW
---------------------------------

   5.1 DEFS.CON
   5.2 USER.CON
   5.3 GAME.CON

-------------------
SECTION 6: APPENDIX
-------------------

   6.1 Things we need to know...
   6.2 Updates and Other Information
   6.3 Where to get this FAQ


==========================
SECTION 1: FAQ INFORMATION
==========================

1.1 About the Authors and General Information
---------------------------------------------

This FAQ was written by Joris Weimar, an avid Duke Nukem 3D FAQ, and a talented con file programmer.  Also working on this FAQ is myself, Jonah Bishop.  I also run the Map Editing FAQ for Duke Nukem 3D and Shadow Warrior.  If you have any questions, tips, corrections or comments about con files or this FAQ, contact Joris via e-mail at: antiwin@worldonline.nl or you can even call him at +31 (0) 70 3520655.

1.2 Were did the author get the information?
--------------------------------------------

Most of the information in this FAQ was obtained by just trying stuff.  However, some information was obtained from the FAQ written by Ben Canterick.

1.3 Revision History
--------------------

* Version 0.1
   - First release.

* Version 0.2
   - Changed the index
   - Added some more primitives

* Version 0.3
   - Expanded the Pigcop example
   - Fixed some misspellings :-)

* Version 0.4
   - Expanded the Pigcop example
   - Added 'Contributor/Thank you's' part
   - Added 'Where to get this FAQ' part

* Version 0.5
   - Added 'Predefined states' part
   - Removed those 'line-drawing' chars for Windows compatibility

* Version 0.6
   - Changed Pigcop into duke :-)
   - Fixed several code pigs

* Version 0.7
   - Removed Pigcop example
   - Started a new more simpler example

* Version 0.8
   - Update the new example
   - Rename keywords to primitives
   - Added 5 new primitives
   - Documented a few unknown primitives

* Versions 0.9 - 1.9
  - Never released

* Version 2.0
  - New example
  - Added new Plutonium Pak primitives

* Versions 2.1 - 2.9
  - Never released

* Version 3.0
  - 5 new examples
  - Some primitives explained
  - Lots of rewritten areas
  - Lots of typos fixed
  - Everything is reformatted
  - Removed Duke Bot example (Due to incomplete code)
  - Additional author added

* Version 3.1
  - Rewrote "palfrom" primitive (Now has the right information)
  - Corrected "mikesnd" primitive
  - Corrected "ifinouterspace" primitive
  - Moved credits section from 6.2 to 1.4

1.4 Credits and Contributors
----------------------------

Thanks to:

- Gavin Lambert : uecasm@geocities.com
  For finding an error in the "mikesnd" primitive and for clearing up the
  usage of the "ifinouterspace" primitive
- Matthew Hill : gambit@proteus.globalnet.co.uk
  For donating the correct "palfrom" primitive parameters
- Reptile : reptile@worldaccess.nl
          : http://www.worldaccess.nl/~reptile
- Linkers : linkers@dds.nl 
          : http://huizen.dds.nl/~linkers

==============================
SECTION 2: CON BUILDING BLOCKS
==============================

2.1 What is a state?
--------------------

A state is a subroutine.  This means that whenever you call a state, it executes the function defined in the state itself, and returns to where you called it.

Here is an example:

state findgoldenapple   // Start and name the state itself.
  quote 150             // This is the code to execute.  Can be multiple
  addphealth 10         // lines of code.
ends                    // End of state.  Now returns to its caller.

The above example is a state (or what is known as a subroutine).  Whenever you call the state, the code that is defined by the state is run.  You use states to code something that you will want to run from various actors or from various places in the con files (this way you don't have to write the same stuff over and over).  The above example does the following when it is called.  Quote number 150 (quotes are defined in user.con, and there is not a number 150.  But I'm just using that number as an example anyway...) is printed on the screen, and the player has 10 points added to his health.  But in order for this state to work, we need to call it from somewhere.  Calling a state function is as simple as typing the following line:

state saysecretplace

By typing that line, you call the state that has the name "eatapple". You can even call a state from within another state like this:

state test2   // Create a state named "test2".
  quote 150
ends          // End of state

state test1       // Create a state named "test1".
  state test2     // Call the state named "test2".
ends              // End the state named "test1".

It's all pretty easy, and we will learn where to put this code in our con files in just a bit.  But now let's move on.

2.2 What is an action?
----------------------

An action is used to give a group of sprites a name. Usually this group of sprites is animated. The structure of the action command is:

action <name> <startframenum> <numframes> <type> <incvalue> <delay>

<name>
This can be any string up to 64 characters long.

<startframenum>
This is the starting frame number.  Note: This number is relative to the main sprite of the actor. If you want the Pigcop to look like the atomic health, you need to give the starting frame a number of -1900 since the Pigcop main character is 2000 and the atomic health is 100 (take the number of the sprite you want to change, and subtract it *from* the number of the sprite you want it to be (if you want to do this at all)).

<numframes>
Number of frames in action group.

<type>
This value determines whether the picture is one sided (looks the same no matter what angle you see it from) or 3D.  When 3D every sprite will contain actually 5 sprites. One seen from the front, one from the back, one sideways and two from 45 degrees and 135 degrees.  The other three angles are created from the other sprites by flipping the x-coordinates. Give <type> a value of 1 to make it one sided. 5 makes it 3D. I don't know if there are any other legal values but I wouldn't bet on it. One possible value could be 8 though. I'm not sure, but when this value is used I guess it expects there to be 8 sprites for each frame (45, 90, 135, etc).

<incvalue>
This is the incrementing value.  Negative values are allowed.

<delay>
This determines how long each frame lasts. Bigger values let the frame last longer.

Here is an example of an action:

action ATOMIC 0 15 1 1 10

This *is* still kind of complex but you'll get to use this stuff in a minute.

2.3 What is an ai?
------------------

An ai is basically a set of code that an actor is to follow (once the ai function is called, that is).  The long name for this would be "Artificial Intelligence Code".  Here is the structure of this command:

ai <ainame> <action> <speed> <aitype>

<ainame>
Just a name to identify it for later use.

<action>
Action group identification.  This is the name of the action that the actor will cycle through when he uses this ai function.

<speed>
The rate of movement of the character when using this ai function.  It seems that <speed> must be a value defined by the move command (move WALKSPEED 100).  Negative values are allowed.

<aitype>
Determines the type of ai.  The ai types are already programmed into the game so you can't change these.  Some of the legal types are:

seekplayer: The actor will walk up to the *nearest* player.

fleeenemy: The actor will run away from a player.

faceplayer: The actor will face in your direction.

faceplayersmart: The actor will 'lead' you a little bit.  In other words, the actor will aim a little before you in the direction that you are heading.

dodgebullet: Evasion maneuver.

randomangle: Change actors direction to a random angle when it hits the wall. Or walk up to the player when actor is being shot at.

You can more than one ai at the same time by listing them in the code that you write - randomangle dodgebullet etc.

When you want the actor to use an ai function do it like this:

ai <name>

<name> is the same as <ainame> explained above.

2.4 What is an actor?
---------------------

Every sprite in the game has the potential to be an actor.  A few examples of actors are:

Duke, Pigcop, medikits, Ammo, Weapon sprites, etc.

The structure of the actor is as follows:

actor <initialspritenum> <strength> <action> <speed> <aifunction>

<initialspritenum>
This number is the tile number (as in Build or Editart) from which all actions that this actor can do are relative.  For a PIGCOP this value is PIGCOP which is defined (in USER.CON) to be 2000.  If you look in build at location 2000 you'll see the PIGCOP character.

<strength>
This value tells the game how much damage it can take.  If you give this parameter a value of 0, the actor can not be destroyed.

<action>
The action number refers to an action group as described above. In terms of monsters, this is usually some kind of initial action group. He is just standing and doing nothing.

<speed>
Speed is the rate of movement this character has.  If you don't want the character to move, give this a value of 0 or don't assign this value at all.

<aifunction>
His initial ai routine.  With monsters, this usually is code telling the monster to wait for someone to discover him.  You can read the definition of ai in the section above.

The actor code is the main code of a character. It's structure goes like this:

actor ... (describer above)

/* The code in this part of the actor is the main code.  Each time the actor being referenced is called (and this happens every frame for most animated actors), the code here is executed.
*/

enda    // End of Actor

In version 1.3D of Duke Nukem 3D, new actors cannot be added.  To add your own actors in this version, you must first get rid of an existing actor (just by deleting the code contained in it).

In versions 1.4 or 1.5, however, you can create your own actors (without having to replace existing ones).  The name for this is the subject of our next section.

2.5 What is a useractor?
------------------------
[This function only works with versions 1.4 and 1.5]

The useractor command is a new addition to versions 1.4 and 1.5.  It allows people to create their own actors without having to replace old ones.  It's almost exactly the same as a conventional actor, but it does have a few exceptions.  For example, enemies created with the useractor command will not shoot straight and their size might not always be proportional (like the bug in BUILD).

The structure of the actor command is as follows:

useractor <type> <initialspritenum> <strength> <action> <speed> <aifunction>

<type>
This tells PP the type of actor you want to create.  The legal values are 'enemystayput', 'enemy' and 'notenemy'. Explanations follow:

enemy : The actor's code will not be executed until approximately 1 second after the player has spotted the actor.

notenemy : The actor's code will not be executed until the player has spotted the actor.

enemystayput : The actor's code will not be executed until approximately 1 second after the player has spotted the actor AND the actor's code will not be executed if the player is not in sight.

<initialspritenum>
This number is the tile number (as in build, Editart) from which all actions that this actor can do are relative. For a PIGCOP this value is PIGCOP which is defined (in USER.CON) to be 2000. If you look in build at location 2000 you'll see the PIGCOP character.

<strength>
This value tells the game how much damage it can take.  If you give this parameter a value of 0 the actor can not be destroyed (bummer).

<action>
The action number refers to an action group as described above. Regarding to monsters this is usually some kind of initial action group. He is just standing and doing nothing.

<speed>
Speed is the rate of movement this character has, if the character doesn't move give this a value of 0 or don't give this value at all.

<aifunction>
His initial ai routine.  With monsters, this usually is code telling the monster to wait for someone to discover him.  You can read the definition of ai in the section above.

2.6 What is an if construction?
-------------------------------

Okay, this is really the power of any programming language. In many occasions you want to execute some code *if* something is true, or *if* something is false. You also want something ELSE to be executed if the condition is false:

IF I AM HUNGRY
   EAT A SANDWICH
ELSE
   WAIT UNTIL LATER

This is a bit of an extreme exaggeration, but it should help you understand exactly what an if statement does.  Here is an example of an if statement in the Duke Nukem 3D code:

ifp ponsteroids
   shoot SHOTGUN
else
   shoot SHRINKER

This code comes from a user made enemy.  The code above simply says the following:

if duke is on steroids
   shoot him with the shotgun
else (if he is not on steroids)
   shoot him with the shrinker

If constructions are not necessarily this easy, however.  Some if statements can include large portions of code, sometimes many pages long.  If you want to execute more than one function, you have to learn to use the braces.  { and }.  Here is an example:

ifp ponsteroids
  {
    shoot SHOTGUN
    sound SHOTGUN_FIRE
  }
  else
  {
    shoot SHRINKER
    sound SHRINKER_FIRE
  }

Now you should see that the code between the braces is considered *one* function.  So if Duke is on steroids, we are to shoot him with the shotgun, and we are to make the shotgun sound.  If he isn't, we should shoot the shrinker and make the shrinker sound.  Do you get it?  You should hopefully understand this part; it's not *too* hard.  :-)

2.7 The Complete Primitive List
-------------------------------

The following list is a list of *everything* that can be put into the code of the actors and state functions.  If there is anything missing from this list, please let us know by dropping by Map FAQ Central (http://mapfaq.3dportal.com) and clicking on the "Found an Error?" link in the left frame.  Then leave us a message of what you found that is missing, and we'll put it in the next version.

//
Everything on the line after this symbol will be ignored.  You use this to make one line (or other short) comments.

/* and */
Everything between these 2 symbols will be ignored.  Place the /* at the beginning of the area you wish to ignore, and the */ at the end of the area you wish to ignore.  This is a nice way to make large comments or to ignore an entire section of code.

action
Assign sprite animation group to current actor.  See section 2.2 for an in-depth description of this function.

actor
See section 2.4 for an in-depth description of this function.

addammo <weapon> <amount>
Add the given number of ammo to the player.  He does not get the weapon if he hasn't got it. The legal values for <weapon> in this primitive can be found in section 3.1.

addphealth <amount>
Add the value <amount> to the players health.  When playing with more than one player I suspect the closest one will be effected.  This goes for all player related functions.  Strangely enough, only the atomic health seems to give the player health above 100%.  Let me know if you are able to get a user actor to add health above the value MAXPLAYERHEALTH.

addinventory <item> <amount>
Add <amount> to the item <item>.  The legal values for <item> can be found in section 3.2.

ai <name>
Let current actor use the ai function <name> from now on.

addstrength <value>
Adds <value> number of strength (i.e. - health or hit points) to the current actor.

addweapon <weapon> <ammo>
Gives nearest duke weapon <weapon> with an initial amount of ammo equal to <ammo>.  Legal values for <weapon> can be found in section 3.3.

break
Immediately leave a STATE or actor.

clipdist <value>
I have no idea what this does.

count <number>
Sets the counter to <number>.  I believe the game gives every actor its own counter since this function could heavily mess up the timer of other actors.

cactor <actor>
Call the code of the actor identified by <actor>.

cstat <mask>
With this function you can do some nice tricks.  This is used to change some actor settings for the current actor.  The legal values for <mask> can be found in section 3.4.

cstator <mask>
Same as cstat, but it doesn't reset all the previous settings. It just adds the ones you specify. A bit like the 'or' in several programming languages.  The values for <mask> can be found in section 3.4.

debris <actiongrp> <amount>
Causes debris to fly all over the place.  <actiongrp> is the sprite animation used for the debris.  Legal values seem to be 'SCRAP1' and 'SCRAP2'.  The higher the amount the more debris.  2 seems to be a reasonable value, but it's up to you.

debug <value>
Prints a <value> on screen.  This value will be printed in the ULGY standard font and Duke will not try to save the background. I don't know what forms <value> can take.  If you know what values are acceptable, let us know.

define <string> <value>
Defines a value as a string.  This way you can use the string instead of the number (easier to remember).  The Duke 3D compiler will replace every occurrence of <string> with <value>.  An example of this would be the definition of maximum player health.

  EXAMPLE: define MAXPLAYERHEALTH 100

definequote <value> <string>
Binds a string to a number.  The string can now be displayed by using the 'quote' primitive.  This is used to make the quotes appear at the top of the screen while in the game.

defineskillname <value> <s>
[Versions 1.4/1.5 Compatible Only]
Defines the string <s> associated with the difficulty level <value>.  0 is easy and 3 is hard.

definelevelname <ep> <lev> <mapname> <par time> <3drealms>
Defines a level where the episode number is <ep>, the level number is <lev>, the map name is <mapname>, the par time is <par time> and 3D Realms' time is <3drealms>.

definesound <value> <filename> <begin pitch> <end pitch> <priority> <flags> <volume>
Binds the sound file <filename> to <value> and tells the game the sound may be pitched from <begin pitch> to <end pitch>.  The sound priority is <priority> and the type of sound is defined in <flags>.  The <volume> value is the volume adjustment.

definevolumename <ep> <name>
[Versions 1.4/1.5 Compatible Only]
Defines title for each episode where <ep> is the episode number and <name> is the name it will get.

enda
End of actor or useractor marker.

endofgame <number>
Ends the game.  I'm not sure what <number> means but 52 is used to end episode 3 (BOSS2).

ends
End of state marker.

fall
Let the current actor fall until it hits a surface.

gamestartup
This is the main function which "starts" the game.  It gets all the hard coded values passed as parameters.  The values that get passed can not be changed during gameplay.  This value is located in USER.CON, so take a look there and see how it is laid out.

getlastpal
Sets the palette of the current actor back to the color before the last change.

guts <actiongrp> <amount>
Same as debris but then for body parts. Legal values for <actiongrp> can be found in section 3.5.  The <amount> value determines the amount of guts to make fly.

globalsound <sound>
Play sound that can be heard everywhere in the map.  The <sound> value is the name of the sound to play (not the filename of the sound).

hitradius <c> <1> <2> <3> <4>
Make an explosion (not the actual animation but just the damage).  The <c> value is the radius, <4> is how much damage is done in first quarter of circle (right near the center of the circle), <3> is how much damage is done in second quarter of circle, etc.

ifactornotstayput
Test if the current actor already <activated>, where <activated> means spotted by a player or he has spotted the player.  It seems that an actors code isn't executed at all until one of the above events occur.  You can notice this in the game.  If you  create a map where an actor (i.e. health) is lifted into the sky, he doesn't fall down to the ground until you spot it!  (I'm not 100% sure about this one).

ifactor <actorid>
Checks if current actor was called with cactor by <actorid>.

ifaction <actionnum>
Test if the current actor is executing the giving <actionnum>. <actionnum> is defined by the action primitive (see section 2.2).

ifactioncount <number>
Tests if the actor has displayed a set <number> of frames since the last call to resetactioncount.

ifai <ainame>
Tests if the current actor is using the ai function <ainame> which was defined with the ai primitive (see section 2.3).

ifangdiffl <angle>
If the angle between the current actor and Duke is less than <angle> it returns true.  360 degrees is 2048.

ifangdiffg <angle>
If the angle between the current actor and Duke is less than <angle> it returns false.  360 degrees is 2048.

ifawayfromwall
Returns false when actor is on a wall-line.  This would be a line that can be seen in  BUILD.EXE.  I don't know the actual use for this.

ifbulletnear
Tests if a bullet is near the current actor.  This primitive can be used to write artificial intelligence (ai) scripts for enemies or other actors.

ifcansee
Tests if the current actor can see Duke.  It also seems to have another function.  It seems as if you need to call this function to give an actor a new position to walk to when using the seekenemy and some other ai functions.  If you don't call this when using that ai function he will just walk up to your previous position and just stop there!

ifcanseetarget
Tests if the current actor can see Duke. I'm not 100% sure about this one though.

ifcanshoottarget
Tests if the current actor can shoot his target.  I don't know exactly what 'can shoot' means.

ifceilingdistg <number>
Tests if the distance to the ceiling is greater than <number>.

ifceilingdistl <number>
Tests if the distance to the ceiling is less than <number>.

ifcount <number>
Tests if the number of frame (I don't actually know how long a frame takes) is reached.  These are not action frames so they are not limited to one actor.  See it as some sort of global counter.

ifdead
Checks if actor has no health left.  Good thing to call after he has been hit with a weapon.  If he was and he's dead you need to remove the actor from the map (killit).

iffloordistg <number>
Same as 'ifceilingdistg' but now for the floor.

iffloordistl <number>
Same as 'ifceilingdistl' but now for the floor.

ifgotweaponce <number>
Seems to test if a player has a particular weapon.  The weapon tested would be the current actor.  This code would logically only appear in weapon actors such as RPGSPRITE.  I'm not sure what the <number>'s use is. The values used in the real CON files were 0 and 1. (?)

ifhitspace
Checks if the player is hitting the spacebar.

ifhitweapon
Tests if the current actor has been hit by a weapon.  Use 'ifwasweapon' to check which weapon it was.

ifgapzl <number>
Tests if the distance between the floor and the ceiling at the actor's location is less than <number>.

ifinspace
Checks if current player is in space. "Space" means when the floor or ceiling is parallaxed and the texture is one of the space textures.

ifinwater
Tests if the current actor is in the water.

ifinouterspace
Returns true if the following parameters are true: "ifinspace" is true and the ceiling (or floor) palette on the BigSpace texture is 0.  This primitive is basically useless, since it is called a split second before the player dies from the vacuum of space.

ifonwater
Tests if the current actor is on top of the water.

ifmove <name>
Tests if variable <name> is greater than 0.  I'm not exactly sure what this does.

ifnosounds
Tests if a sound is playing.

ifnotmoving
Tests if the current actor is moving.  Not sure about this one.

ifspawnedby <actor>
Checks if the actor who spawned an item is equal to <actor>.

ifspritepal <number>
Tests if the palette of the current actor is equal to <number>.

ifsquished
Tests if the current actor has been squished.

ifoutside
Tests if player is outside.  A player is outside when he is in a room with parallaxing on.

ifp  <type>
Tests if Duke is doing something specified by the <type> value.  Legal values for <type> can be found in section 3.6.  You can test for more things at the same time.  "ifp prunning pwalking"' returns true when either of the two is true.

ifpdistl <number>
Tests if the players (nearest player) distance if less than <number>. 1024 appears to be the largest grid in BUILD.

ifpdistg <number>
Same as ifpdistl but he now tests if the distance is greater.

ifphealthl <number>
Tests if the players health is less than <number>.

ifphealthg <number>
Tests if the players health is greater than <number>.

ifpinventory <item> <amount>
Tests if the nearest player has less than <amount> left of item <item>.  The legal values for <item> can be found in section 3.2.

ifrespawn
Tests if the monster-respawn-mode is on.  If so, the actor needs to respawn after RESPAWNTIME.

ifrnd <number>
This is a randomize function.  The <number> value is the chance you give it to be true.  If <number> is 256 it will always be true, and if <number> is 128 it will be true 50% of the time.  If you want less than a 1/256 chance, you will need to use two ifrnd's like this:
    ifrnd 1
      ifrnd 128  // This code gets executed 1/512.

ifsquished
Tests if the current actor has been squished (shrunken and stepped on).

ifstrength <number>
Tests if current actor has <number> strength left.

ifwasweapon <weapon>
Tests what weapon the actor has been hit by.  The legal values for <weapon> can be found in section 3.7.

include <filename>
Includes <filename> in the compiling process.

killit
Removes the current actor from the map. The code for that actor won't be called anymore.

lotsofglass <amount>
Spawns glass all over, much like when a window has broken.  The <amount> value determines the amount of glass.  30 seems to be a reasonable value.

mail <number>
[Versions 1.4/1.5 Compatible Only]
Spawn some letters.  This is normally used for the mail bags that appear in the level "Going Postal".  The <number> value is the amount of mail to spawn.

mikesnd
Plays the sound assigned to the microphone sprite in Build (the microphone sprite's hitag is the sound number to be played).

money <number>
Spawns a user defined <number> of dollar bills.

move <name> <v1> <v2>
Give <name> a value of <v1> and a optional value of <v2>.  The <v1> value is used to define the speed of an actor and the <v2> value is used for vertical speed.  This way you can simulate a character using a jetpack.  I've also seen <v1> and <v2> to be given an ai function.  What the meaning of that is I'm not entirely sure.  If you change the velocity of an actor during it's code it will automatically update.

music <ep> <m1> <m2> ...
Defines MIDI music for each episode where <ep> is the episode number and <m1>, <m2>, etc. are the individual music files for each level.

nullop
The nullop primitive equals { }.  Now you can say:
  ifspritepal 1 nullop else { quote 1 }
instead of
  ifspritepal 1 { } else { quote 1 }

operate
Let's the current actor operate.  If a door is nearby the door will open.  This is a nice function for a clever actor.  This actor could open a door which you just fled through.  You would have something like this in your main code:
  ifrnd 1 operate
You *don't* want to operate every time because the second time you operate the door closes again.

palfrom <intensity> <red> <green> <blue>
Flashes a certain color (specified by the user) on the screen when called from a function.  The values for each of the above can be anything between 0-63.  The red, green, and blue values can be mixed to make the screen any color upon flashing.  Leaving off the green or blue values is the same as assigning them a value of 0.  For smaller effects, the recommended intensity level is between 10 and 20.  For larger effects, 40+ is recommended.

paper <number>
[Versions 1.4/1.5 Compatible Only]
Spawns some paper, which floats down to the ground.  This is normally used for the "top secret" files folder which comes apart when an explosion hits near it.  The <number> value is the amount of paper to spawn.

pstomp
Player will look down and step on the nearest actor (if one is near).

pkick
Player will kick.  Good to call from an actor who has been frozen.  First do "ifp pfacing" then "ifpdistl FROZENQUICKKICKDIST" then "pkick".

quote <number>
Print quote <number> on screen.  All quotes are defined in USER.CON.

resetactioncount
This resets the counter that counts how many frames of the current actor have been executed.  The speed of actioncount is determined by the <delay> parameter in the action structure.

resetcount
This resets the global count.  This is the counter that is not bound to a given actor but count at the same rate for every actor.  I believe the counter increments every 3/100th of a second.

resetplayer
Resets the player in a multiplayer game and places him at one of the APLAYER locations.

respawnhitag
This code seems to spawn the actors that need to be spawned when the current actor dies.  An example of this would be the dancing girls in the bar in E1L2.

shoot <weapon>
Let's the current actor shoot with <weapon>.  Legal values for <weapon> can be found in section 3.7.  The direction in which the actor shoots is determined by the AI function of the actor.  If it is 'faceplayer' he will obviously shoot at the player.  But if you have 'seekplayer' as AI function the actor may be heading to the player but since he doesn't go straight to him he can easily miss.

sizeat <x> <y>
Immediately makes the current actor <x> times smaller in x-direction and <y> times smaller in y-direction.

sizeto <x> <y>
Gradually makes the current actor <x> times smaller in x-direction and <y> times smaller in y-direction.

sleeptime <time>
Makes the current actor sleep for <time> counts.  (?)

sound <soundnum>
Play a sound.  The sound numbers are defined in USER.CON.

soundonce <soundnum>
When using soundonce, the sound will not be activated again until it is finished playing.

spawn <actor>
Bring a new actor into the map defined by <actor>.  There seems to be once special <actor> (there may be more) which has a unique effect on the current actor.  When you spawn 'FRAMEEFFECT1' the current actor will blur.  This effect can be seen when an actor is shrinking or a player is on steroids.

spritepal <number>
Changes palette number of sprite.  Legal values for <number> can be found in section 3.8.

state <statename>
Enter a state named <statename> and return from it.  If this line is put out of any actor or state code it is interpreted as a state definition.

stopsound <sound>
Stops to play the sound 'sound'.  Good for ending long sound effects when they have no use anymore.

strength <number>
This function changes the strength of the current actor in <number>.

tossweapon
Let's duke spawn his currently selected weapon with a 50% chance.  This code gets called when Duke dies.

wackplayer
Tilts the screen.  As if you're struck by lightning.

2.8 Predefined State Functions
------------------------------

The following is a listing of (most) state functions that already exist in the GAME.CON file.  You can alter these to your liking, but the default functions are described here.  The states are listed in order of appearance (at least in the 1.4/1.5 CON files).

- jib_sounds
Plays one of those nice sounds like "What a mess" or "Let God sort em' out".

- standard_jibs
Spawns some random body parts.

- genericshrunkcode
Shrink an actor and stomp on it if you are within the correct distance.

- genericgrowcode (Versions 1.4/1.5 Only)
Make the current actor grow and then explode.

- blimphitstate
Spawn an explosion and debris, kill the actor, and some other stuff...

- rats
Spawn some rats.

- toughgalspeech (Versions 1.4/1.5 Only)
The sounds to play when the tough girl talks.

- jibfood (Versions 1.4/1.5 Only)
Make food disappear when shot and spawn some gross jibs.

- breakobject (Versions 1.4/1.5 Only)
Used to make all the objects in the Plutonium Pak that are breakable, break when shot by Duke.

- headhitstate
Gets called when player is hurt badly.  The screen tilts when the player gets hit and his health is very low.

- burningstate
Set the current actor on fire.

- steamcode
Update steam sprite, subtract health from player who is near, etc.

-random_ooz (Versions 1.4/1.5 Only ???)
Spawns some ooze.

- burningbarrelcode
Code for a burning barrel.

- getcode
Gets an item and prepares it for respawn if necessary.

- randgetweapsnds
Plays a random sound when a weapon is picked up by the player.  Examples are "Groovy" or "Come get some!".

- getweaponcode
Gets the current weapon and prepares it for respawn if necessary.

- respawnit
Respawns items in a multiplayer game.

- quikget (Versions 1.4/1.5 Only ???)
Get code for the atomic health or other items.

-quikweaponget (Versions 1.4/1.5 Only ???)
Get code for weapons.

- firestate
Updates flames, checks to see if Duke is burning himself, etc.

- drop_ammo (Versions 1.4/1.5 Only ???)
Drops ammo if the odds for dropping it are right.

- drop_battery (Versions 1.4/1.5 Only ???)
Drops battery (?) ammo if the odds for dropping it are right.

- drop_sgshells (Versions 1.4/1.5 Only ???)
Drops shotgun ammo if the odds for dropping it are right.

- drop_shotgun (Versions 1.4/1.5 Only ???)
Drops shotgun if the odds for dropping it are right.

- dropchaingun (Versions 1.4/1.5 Only ???)
Drops chaingun if the odds for dropping it are right.

-random_wall_jibs
Spawns blood on the walls when an enemy is shot and near a wall.

- femcode
Takes care of the females in the game.  Kill them or let them show their boobs.

- killme
Lets some women say "kill me" when Duke hits [SPACE] near her.

- tipme
Lets Duke give some women a dollar bill and say "Wanna dance" or "Shake it baby".

-toughgaltalk (Versions 1.4/1.5 Only)
Make the tough girl talk when the player presses [SPACE].

- troop_body_jibs
Spawns some trooper body parts.

- liz_body_jibs
Spawns some lizard body parts.

- standard_pjibs
Spawns some Duke body parts.

- handle_dead_dukes (Versions 1.4/1.5 Only ???)
The code for making blood pools, etc. when Duke dies.

- check p_standard
Makes the animations of Duke walking when walking, jumping when jumping, etc.

- rf (Versions 1.4/1.5 Only ???)
Changes the cstat to 4 ifrnd 128, else it makes the cstat 0.  (Usage?)

There are too many enemy states to put here, but they all cover the basic artificial intelligence routines for each enemy.

2.9   Known .CON Bugs
---------------------

I added this section since I discovered a bug.  I'll bet there will be more.

Bug #1:

This 'if' construction...

ifcansee
  ifai AIDUKEWANTTOSTOMP
    {
    }
    else
    ai AIDUKEWANTTOSTOMP

...should be equal to...

ifcansee
  {
  ifai AIDUKEWANTTOSTOMP
    {
    }
    else
    ai AIDUKEWANTTOSTOMP
  }

... but it isn't. In the first case the 'else' part always gets executed.  *Huge* bug.

I don't know if it's a bug or not but it sure is strange.  When you give a character like a Pigcop a huge amount of strength like 4500 then he will move like thunder when you hit him with a RPG.

2.10 Things You Cannot Change
-----------------------------

There are several things that people think they can change when editing the con files, but these objects are all hard coded into the game itself and cannot be changed.  The list of items that cannot be changed by editing the con files are as follows:

* Weapon firing rates
* Weapon projectile systems
* Glass bottle code
* 

=======================
SECTION 3: LEGAL VALUES
=======================

3.1 Values for addammo
----------------------

    KNEE_WEAPON
    PISTOL_WEAPON
    SHOTGUN_WEAPON
    CHAINGUN_WEAPON
    RPG_WEAPON
    HANDBOMB_WEAPON
    SHRINKER_WEAPON
    DEVISTATOR_WEAPON
    TRIPBOMB_WEAPON
    FREEZE_WEAPON
    HANDREMOTE_WEAPON
    GROW_WEAPON

3.2 Values for addinventory and ifpinventory
--------------------------------------------

    GET_STEROIDS
    GET_HEATS
    GET_BOOTS
    GET_SHIELD
    GET_SCUBA
    GET_HOLODUKE
    GET_JETPACK
    GET_FIRSTAID
    GET_ACCESS*

* Note: When using this value, the amount seems to be a bit list of cards that Duke has.  0 = no cards, 1 = blue card, etc.).

3.3 Values for addweapon
------------------------

    HANDBOMB_WEAPON
    RPG_WEAPON
    SHOTGUN_WEAPON
    PISTOL_WEAPON
    TRIPBOMB_WEAPON
    CHAINGUN_WEAPON
    SHRINKER_WEAPON
    FREEZE_WEAPON
    DEVISTATOR_WEAPON

3.4 Values for cstat and cstator
--------------------------------

    1 = Make sprite blockable ("B" in BUILD)
    2 = Make sprite 'see-through'
    4 = Flip sprite around x-axis
    8 = Flip sprite around y-axis
    16 = Draw sprite as wall texture (vertically flat)
    32 = Draw him as floor texture (horizontally flat)
    64 = Make sprite one sided
    128 = Half submerged
    256 = Make sprite solid ("H" in BUILD)
    32768 = Invisible

Note: To use more than one setting add the values together (264 = solid (256) + upside-down (8).  256 + 8 = 264).

3.5 Values for guts
-------------------

    JIBS1
    JIBS2
    JIBS3
    JIBS4
    JIBS5
    JIBS6
    HEADJIB/LEGJIB/ARMJIB  (trooper parts)
    LIZMANARM1/LIZMANLEG1  (lizman parts)
    DUKETORSO/DUKELEG/DUKEGUN (duke parts)

3.6 Values for ifp
------------------

    pstanding    = Duke is standing
    pwalking     = Duke is walking
    prunning     = Duke is running
    pducking     = Duke is ducking
    pfalling     = Duke is falling
    pjumping     = Duke is jumping
    phigher      = Duke is higher than the current actor (?)
    pwalkingback = Duke is walking backwards
    prunningback = Duke is running backwards
    pkicking     = Duke is kicking
    pshrunk      = Duke is has been shrunk
    pjetpack     = Duke is flying with the jetpack
    ponsteroids  = Duke is using his steroids
    ponground    = Duke has his both feet on the ground
    palive       = Duke hasn't died yet
    pdead        = Duke has been killed
    pfacing      = Duke is facing the current actor

3.7 Values for ifwasweapon and shoot
------------------------------------

    KNEE
    SHOTSPARK1 (The Pistol)
    SHOTGUN
    CHAINGUN
    RPG
    SHRINKSPARK
    GROWSPARK
    DEVISTATORBLAST
    TRIPBOMB
    FREEZEBLAST
    FIRELASER
    SPIT
    HEAVYHBOMB
    BOUNCEMINE
    MORTER
    RADIUSEXPLOSION
    COOLEXPLOSION1
    FIREEXT

3.8 Values for spritepal
------------------------

    1  = Blue
    4  = Dark
    6  = Night vision Green
    7  = Yellow
    8  = Green
    10 = Red
    19 = "Tomato" Red
    22 = Almost normal

=======================
SECTION 4: EXAMPLES
=======================

4.1 Example 1: Increase Duke Nukem's Health
-------------------------------------------

Difficulty Level: Easy

To start out on the CON editing path, let's do something extremely easy.  We are going to increase Duke Nukem's maximum health from 100 to 200.  We also need to increase his Atomic Health (we'll take it to 400) so that picking up Atomic Health actually does something!

First, open up the user.con file, and scroll down until you see the following line:

define MAXPLAYERHEALTH 100

Now change that number, so that the line looks like this:

define MAXPLAYERHEALTH 200

Now look for the line that looks like this:

define MAXPLAYERATOMICHEALTH 200

And change it to this:

define MAXPLAYERATOMICHEALTH 400

Now you are finished!  Easy huh?  Well, we'll now move on to something a little more difficult.

4.2 Example 2: Rubber Trash Cans Spawn Health When Destroyed
------------------------------------------------------------

Difficulty Level: Easy

In this example, we will make the rubber trash can spawn health, but only 50% of the time, when it is destroyed by an explosion.

Open the game.con file and scroll down to these lines of code:

actor RUBBERCAN WEAK
    ifaction RUBCANDENT
    {
      ifactioncount 16
      { 
        strength 0
        action RUBCAN
        break
      }
    }
    else ifhitweapon
    {
      ifwasweapon RADIUSEXPLOSION
      {
        state rats
        ifrnd 48
          spawn BURNING
        debris SCRAP3 12
        killit
      }
      else action RUBCANDENT
    }
enda

We need to add the following lines to the code in order to make the health spawn 50% of the time (instead of the rats).

ifrnd 128  // 50% of the time...
  spawn COLA  // ... spawn the +10% health ...
  killit // ... then delete the trashcan from the map.
else
  (Here we put the rest of the code)

But where do we put this set of code?  Well, we first have to find where the code checks to see if the trash can has been hit by an explosion.  You see that line that says ifwasweapon?  That line of code checks to see if the trashcan was hit by the weapon stated there; the RADIUSEXPLOSION.  So we need to place the weapon right in that section of code.  The finshed product will look like this:

actor RUBBERCAN WEAK
    ifaction RUBCANDENT
    {
      ifactioncount 16
      { 
        strength 0
        action RUBCAN
        break
      }
    }
    else ifhitweapon
    {
      ifwasweapon RADIUSEXPLOSION
      {
        ifrnd 128
        {
          spawn COLA
          killit
        }
        else
        {
          state rats
          ifrnd 128  // See note #1.
            spawn BURNING
          debris SCRAP3 12
          killit
        }
      }
      else action RUBCANDENT
    }
enda

NOTE #1: Notice that we changed the ifrnd statement from 48 to 128.  Why did we do that?  Well, when you stack ifrnd statements up like they are, the chances of something happening are very small.  For example:

ifrnd 128
  ifrnd 128

This statement tells the sub-code to happen only 25% of the time.  How did I get that number?  Well, the value of 256 is 100%, so the value of 128 is 50%.  Then 50% of 50% is 25%.  If it sounds confusing, just work through it again and you should pick it up.

4.3 Example 3: Booby-trapped Ammunition
---------------------------------------

Difficulty Level: Intermediate

In this example, we will make chaingun ammo turn deadly - but only for 25% of the time.

Let's take a look at the chaingun ammo code, which can be found in the GAME.CON file:

actor BATTERYAMMO
    fall
    ifmove RESPAWN_ACTOR_FLAG
      state respawnit
    else ifp pshrunk 
      {
      } 
    else ifp palive
      ifpdistl RETRIEVEDISTANCE
        ifcount 6
          ifcanseetarget
           {
             addammo CHAINGUN_WEAPON CHAINGUNAMMOAMOUNT
             quote 63
             ifspawnedby BATTERYAMMO
               state getcode
             else
               state quikget
           }
enda

You see all those if statements there under the second else?  That is the area that we want to add our code to.  We need to add the following lines to the code, so that 25% of the time, the chaingun ammo explodes.

ifrnd 64   // 25% of the time, the following code should be executed.
{
  hitradius 1024 WEAKEST WEAK MEDIUMSTRENGTH TOUGH  // define the damage
  spawn EXPLOSION2  // make the explosion
  debris SCRAP2 2   // make some debris fly around
  sound PIPEBOMB_EXPLODE  // make an explosion sound
  killit  // delete the chaingun ammo from the map
}
else  // in other cases, add the ammo amount to the player.
{
  addammo CHAINGUN_WEAPON CHAINGUNAMMOAMOUNT
  quote 63
  ifspawnedby BATTERYAMMO
    state getcode
  else
    state quikget
}

So let's add our code to the ammunition.  This is what the final product will look like:

actor BATTERYAMMO
    fall
    ifmove RESPAWN_ACTOR_FLAG
      state respawnit
    else ifp pshrunk 
      {
      } 
    else ifp palive
      ifpdistl RETRIEVEDISTANCE
        ifcount 6
          ifcanseetarget
            ifrnd 64
            {
              hitradius 1024 WEAKEST WEAK MEDIUMSTRENGTH TOUGH
              spawn EXPLOSION2
              debris SCRAP2 2
              sound PIPEBOMB_EXPLODE
              killit
            }
            else
            {
              addammo CHAINGUN_WEAPON CHAINGUNAMMOAMOUNT
              quote 63
              ifspawnedby BATTERYAMMO
                state getcode
              else
                state quikget
            }
enda

Now, when you go into the game, every 25% (or roughly) of the time you should get hurt by an explosion.  Cool way to make booby-traps, huh?

4.4 Example 4: Break the "Unbreakable" Plate (Versions 1.4/1.5 Only)
--------------------------------------------------------------------

Difficulty Level: Intermediate

If you have ever played through Duke Nukem, you should hopefully have noticed the "unbreakable" plate in the sushi bar (episode 3, level 1).  There is one plate the 3D Realms forgot about coding, and so it cannot be broken like the others can.  What better a mistake for us to fix!

This coding session will only work with versions 1.4 or 1.5 of Duke Nukem 3D, because we will need to make use of the "useractor" function.

The plate that is in question is in slot #851 (you can take a look at it in Build or Editart).  To make this slot an actor, we first need to define it in the defs.con file.  Open up the defs.con file, and place the following line somewhere in this file:

define SUSHIPLATE99 851

I prefer putting these types of lines in order of appearance by tile number, much like 3D Realms did.  Scroll down to the lines that say:

define MASKWALL13 830
define HURTRAIL 859

and put our define statement between the two lines that are there (because 851 is between 830 and 859).

Now save your work and close this file.

Now open the game.con file and place the following lines of code anywhere in the file:

useractor notenemy SUSHIPLATE99 WEAK  // define it as a useractor
  ifhitweapon  // if it is hit by a weapon...
  {
    lotsofglass 7   // ... make some glass fly around ...
    sound GLASS_BREAKING   // ... make the glass breaking sound ...
    killit   // ... and kill the plate (delete it from the map).
  }
enda

Now, when you enter into the game, you can shoot the plate and it will break!  Yay!  We just fixed a bug in Duke Nukem 3D!

4.5 Example 5: Make Duke eat some food (Versions 1.4/1.5 only)
--------------------------------------------------------------

Difficulty Level: Intermediate

In this example, we are going to make use of the food that appears in a few of the levels in Episode 4 (Versions 1.4 and 1.5 only).  We will make Duke eat the food when he is near enough to it, and we will add 10 health points to his health when he eats it.  We also will make him say "Oooh, I needed that!" when his health is below 20.

First, open up the user.con file, and scroll down to the line that says:

definequote 124       MAP HAS A DIFFERENT NUMBER OF PLAYERS

This is the last quote defined by 3D Realms, so we will make 2 new quotes to print.  Add these lines right below the definequote 124:

definequote 125       YOU EAT SOME FOOD: +10 HEALTH!
definequote 126       YOU AREN'T HUNGRY NOW...

We will use these quotes when we add code to the game.con file.  Save your work and close user.con.

First we need to make a state function.  Open the game.con file and put the following lines of code at the top of the file:

state eatfood  // We first define the state function.
  ifp pfacing  // If Duke if facing the food actors...
    ifpdistl 1280  // and he is 1280 units away from them...
      ifhitspace  // and he presses the space bar...
      {
        ifphealthl 20  //and if his health is below 20...
        {
          addphealth 10  // add 10 points to his health...
          globalsound DUKE_NEED  // make him say "I needed that"...
          quote 125  // print a quote on the screen...
          killit  // and kill the food actor (delete it).
        }
        else  // in other cases than Duke having health below 20...
        {
          ifphealthl MAXPLAYERHEALTH  // if his health is below 100...
          {
            addphealth 10  // add 10 points to his health...
            quote 125  // print a quote on the screen...
            globalsound DUKE_GET  // make the generic get item sound...
            killit  // delete the item from the map
          }
          else  // if his health is not below 100
          {
            quote 126  // print a quote on the screen...
            break  // get out of this code (leave the food where it is)
          }
        }
      }
ends

Now we need to find where the actors are located.  Scroll down to the line that says:

useractor notenemy FOODOBJECT11 WEAK state breakobject enda

and change it to look like this:

useractor notenemy FOODOBJECT11 WEAK
  state breakobject
  state eatfood
enda

This now allows our state function to work on FOODOBJECT11.  But we want to change 12 through 20 as well.  So just make each useractor that we want to change look just like the useractor above.  Example:

useractor notenemy FOODOBJECT12 WEAK  // We change # 12 now...
  state breakobject
  state eatfood
enda

Save your work, and when you go into the game, you will find that you can now press space near the food and you will gain 10 health points if you are below 100!

=================================
SECTION 5: A GENERAL CON OVERVIEW
=================================

5.1 DEFS.CON
------------

This file is where all of the basic definitions are made; defining objects makes it much easier when coding.  You can assign a name to a value (usually the location of a piece of artwork), and you can then use that name instead of the value when writing your code.  The game.con file includes this con file at compile time.

5.2 USER.CON
------------

User.con defines a bunch of other stuff that is not included in the defs.con file.  Here you can find the strengths of weapons, ammo amounts of weapons, player health limits, quotes, names of levels, names of sounds, names of episodes and difficulty levels (Version 1.4 and 1.5 only), and more!  This is the best con file to play around with if you don't intend to seriously get into con file hacking.  The game.con file also includes this con file at compile time.

5.3 GAME.CON
------------

This is the biggest and the best of the con files.  This file gets compiled first, and it contains all the code for every object in the game (there are a few objects that are hard coded into the game itself, and they cannot be edited).  This is the main file you will be working with if you intend to get serious about con file programming.

===================
SECTION 6: APPENDIX
===================

6.1 Things we need to know...
-----------------------------

The following is a list of things that we need to know.  If you do know about these items, *please* send us some mail regarding it.

- Why is "ifcansee" needed to let seekplayer and other ai functions work properly?

- Explanation of some of the ai functions.

- What does ifnotmoving do?  Is this necessary due to a bug in the ai functions?

6.2 Updates and Other Information
---------------------------------

Updates to this FAQ can be found at Dukeworld and at Map FAQ Central (see section 5.4 for the URLs to these sites).  If you find errors in this FAQ, and if you find something that isn't in here, send mail to anitwin@worldonline.nl and we will change or add the information for the next release.

6.3 Where to get this FAQ
-------------------------

This FAQ can be found at Dukeworld and at Map FAQ Central.

Dukeworld - http://www.dukeworld.com

Map FAQ Central - http://mapfaq.3dportal.com