Release date: 12/27/1996 12:55


                       ---  CON Editing FAQ  ---

                              version 2.0

                                  by

                            Joris B. Weimar


--------------------------------------------------------------------------
 INDEX
--------------------------------------------------------------------------

1)    Information

1.1   Who wrote this FAQ and some general info
1.2   Where did the author get the information?
1.3   What's new?

2)    CON building blocks

2.1   What's a state?
2.2   What's an action?
2.3   What's an ai?
2.4   What's an actor?
2.5   What's an useractor?
2.6   What is an 'if' construction?
2.7   The complete primitive list
2.8   Predefined states
2.9   Known .CON bugs

3)    Examples

3.1   Example 1: Make the atomic health sprite pulsating
3.2   Example 2: Make your own Duke Bot

4)    General CON overview

4.1   DEFS.CON
4.2   USER.CON
4.3   GAME.CON

5)    Appendix

5.1   What I would like to know
5.2   Contributers/Thank you's
5.3   Update and info
5.4   Where to get this FAQ

--------------------------------------------------------------------------
  1.1 Who wrote this FAQ and some general info
--------------------------------------------------------------------------

This FAQ was written by Joris Weimar also known as 'antiwin'. I'm a huge
fan of Duke Nukem and until recently I didn't do anything with the CON
files other then change some simple values such as MAXPLAYERHEALTH etc.
After some of the primitives you will notice a sign like this "[PP]".
This will mean the primitive or functionallity is only available in
Plutonium Pak. PP is short for Plutonium Pak (do'h!).
   I must admit that I'm don't know everything on .CON hacking but I know
when *I* knew nothing about it I wanted to get every information I could.
So here it is. Whenever I searched the net for a CON FAQ I _always_ got
the same FAQ. I hope this FAQ will go furhter into subjects that that FAQ
(you surely now which FAQ I'm reffering to) brought up. I'm asking you
friendly to keep the name of this FAQ 'CONEDIT.FAQ' or 'CONEDIT.ZIP' when
zipped. This to eliminate confusion.
   If you have any questions, tips, corrections or comments about this FAQ
you can reach me via e-mail at antiwin@worldonline.nl. You can also call me
at +31 (0)70 3520655.

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

Well, I _did_ learn something from the FAQ by Ben Cantrick. But most of
the stuff I found out by myself by just trying, trying and trying. I re-
wrote the entire code for the pigcop. It's still buggy and there are still
some things that I don't comprehense. But he sure has gotten tougher.
You'll find an PigCop-to-Duke example in this FAQ. Ok, now lets get on
with the good stuff.

--------------------------------------------------------------------------
  1.3 What's new?
--------------------------------------------------------------------------

* 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 compatiblity

* 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

* version 0.9 - 1.1
  - never released

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

--------------------------------------------------------------------------
  2.1 What's a state?
--------------------------------------------------------------------------

A state is a subroutine. Whenever you call a state he executes that
function and return to where you called it.

Example:

state saysecretplace    // Start a state definition
quote 9                 // Some code
ends                    // End of state (return to caller)

This is a state (subroutine). Whenever you call it it executes the code
contained in it. In this example that would be the command 'quote' which
prints a text on screen. 9 is the defined in USER.CON (definequote) as
"A SECRET PLACE!". Now we must call it from somewhere:

state saysecretplace // execute the state, thus printing "A SECRET PLACE!"

You can call a state from within a state like this:

state test2   // State test2 definition
quote 9
ends          // End of state

state test1   // State test2 definition
state test2   // Call the test2 state
ends          // End of state


Now to print the quote on screen do this:

state test1

or ofcourse this (this does it directly while the above example first
calles another state):

state test2

Now he will print "A SECRET PLACE!". You may think to yourself: "hmmm... I
can understand this but where do I put it in the .CON". Well, I'll get to
that later.

--------------------------------------------------------------------------
  2.2 What's 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> = starting frame number. Note: this number is rela-
                  tive 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

<numframes>     = Number of frames in action group.

<type>          = This value determines wether the picture is onesided
                  (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 upfront, one from the
                  back, one sideways and two from resp. 45 degr. and 135
                  degr. The other three angles are created from the other
                  sprites by flipping the x-coordinates. Give <type> a
                  value of 1 to make it onesided. 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 the expects
                  there to be 8 sprites for each frame (45,90,135degr etc.)

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

<delay>         = This determines how long each frame lasts. Bigger values
                  lets the frame take longer.


Example:

action ATOMIC 0 15 1 1 10

Ok, this _is_ still kind of complex but you'll get to use this stuff in
a minute.

--------------------------------------------------------------------------
  2.3 What's an ai?
--------------------------------------------------------------------------
An ai is some sort of definition of a state of an actor. Here's the struc-
ture:

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

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

<action>           = action group id. This is the group of frames
                     the actor will cycle through as he is using this ai
                     function.

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

<aitype>           = Determines type of ai. The ai types are already
                     programmed in 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 point his crosshair at
                                      you thus facing you.

                     faceplayersmart: The actor will point his crosshair
                                      a little bit next to you in the direction
                                      that you're heading. Kind of smart, isn't
                                      it.

                     dodgebullet:     Evasion manouvre.

                     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: randomangle dodgebullet etc.


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

ai <name>

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

--------------------------------------------------------------------------
  2.4 What's an actor?
--------------------------------------------------------------------------

Everything that has vertices (drawn in build) is _not_ an actor. So walls,
floors, elevators, doors are _not_ actors. Every sprite has the potential
of being an actor. Some examples are:

Duke, Pigcop, Medicalkit, Health, RPG sprite etc...

The structure of the actor command is:

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

<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 de-
                     scribed above. Regarding to monsters this is usally
                     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 is usually
                     a still standing monster waiting for someone to discover
                     him. You can read the defenition 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 contained hereign is the main code of the character. Each time
// (frame) this code gets called!

enda    // End of Actor

As I heard from "StratonAce" we can not add new actors. We can replace
other actors by removing the old code and placing in our. "StratonAce"
also informed me that this restriction is possibly removed with the
upcoming Plutonium Pak version of Duke (1.4)

--------------------------------------------------------------------------
  2.5   What's an useractor? [PP]
--------------------------------------------------------------------------

The useractor command is new to PP. It allows people to create their
own actors in PP without having to replace old ones. It's almost exactly
the same as a conventional actor with a few exeptions. 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:

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'. Explenations follow:

                     enemy        = The actor's code will not be executed until
                                    approximatly 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
                                    approximatly 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 de-
                     scribed above. Regarding to monsters this is usally
                     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 is usually

--------------------------------------------------------------------------
  2.6   What's an 'if' construction?
--------------------------------------------------------------------------

Okay, this is really the power of any programming language. In many
occasions you want to execute some code (listed below, 2.6) IF some-
thing 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

Well, now to get a bit more in Dukes direction, this is some code of
my new Pig Cop. He fires a SHRINKER, but only when you're not on ste-
roids because when you use steroids you won't shrink (you knew that,
right?):

ifp ponsteroids
   shoot SHOTGUN
   else
   shoot SHRINKER

in PSEUDO code that is:

if duke is on steroids
   shoot him with the shotgun
   or else
   shoot him with the shrinker

If you didn't know the 'ifp ponsteroids' and 'shoot' command yet, don't
worry. They are all listed below. Ofcourse you may want to execute MORE
than one function. Then you'll have to use the braces '{' and '}'.

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

You see that all the code between the two braces is considered as ONE
function.


--------------------------------------------------------------------------
  2.7   The complete primitive list
--------------------------------------------------------------------------

Now, you're wondering, what kind of code can I put in these actors and
STATEs. Well, you already saw one of them: QUOTE. That's ofcourse not
enough to create a character like for example a PigCop. Ok, here are
the most important functions:

//                           = Everything on the line after the '//' will
                               be ignored.

/* ... */                    = Everything between the '/*' and the '*/' will
                               be ignored.
action <actiongroup>         = Assign sprite animation group to current
                               actor. See definition above.

actor ...                    = See definition above.

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 are describer in USER.CON

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.

addinventory <item> <amnt>  = Add <amount> to the item <item>. The legal
                               values for <item> can be seen with the
                               'ifpinventory' function.

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

addstrength                  = Adds strength to the current actor.

addweapon <weap> <ammo>      = Gives nearest duke weapon <weap> with an initial
                               amount of ammo equal to <ammo>.
                               Legal weapons are:
                               - HANDBOMB_WEAPON
                               - RPG_WEAPON
                               - SHOTGUN_WEAPON
                               - PISTOL_WEAPON
                               - TRIPBOMB_WEAPON
                               - CHAINGUN_WEAPON
                               - SHRINKER_WEAPON
                               - FREEZE_WEAPON
                               - DEVISTATOR_WEAPON

break                        = Immediatly leave a STATE or actor.

clipdist <value>             = I have no idea ;)

count <num>                  = Sets the counter to <num>. 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. Some of the legal values are:
                               1      = Make sprite blockable ("B" in BUILD)
                               2      = make actor 'see-through'.
                               4      = flip sprite around x-axis.
                               8      = flip sprite around y-axis.
                               16     = Draw him as wall texture (vert. flat)
                               32     = Draw him as floor texture (hor. flat)
                               64     = Make sprite one sided.
                               128    = Half submerged.
                               256    = Make sprite solid ("H" in BUILD)
                               32768  = Invisible
                               To use more than one setting add the values
                               together (264 = solid+upsidedown, 256+8).

cstator <mask>               = Same as cstat, but it keeps doesn't reset
                               all the previous settings. It just adds the
                               ones you specify. A bit like the 'or' in
                               several programming languages.

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
                               now what forms <value> can take.



define <string> <value>      = Defines a value as a string. This way you can
                               use the string instead of the number (easier to
                               remember). The Duke3D compiler will replace every
                               occurance of <string> with <value>

definequote <value> <string> = Binds a string to a number. The string can now
                               be displayed by using the 'quote' primitive.

defineskillname <value> <s>  = Defines the string 's' associated with the
                               difficulty level 'value'. 0 is easy and 3
                               is hard.
                               [PP]

definelevelname <ep> <lev>
                <mapname>
                <par time>
                <3drealms>   = Defines a level where the episode number is
                               'ep' the level number if 'lev' the mapname
                               is 'mapname' the partime is 'par time' and
                               3drealms' 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'. Volume is the volume adjustment.

definevolumename <ep> <name> = Defines title for each episode. 'ep' is the
                               episode number and 'name' is the name it will
                               get.
                               [PP]

enda                         = End of actor code marker.

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

ends                         = End of state code 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 hardcoded values passed
                               as parameters. The values it gets passed can not
                               be changed during gameplay.

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 bodyparts. Legal
                               values for <actiongrp> seem to be:
                               - JIBS(1 to 5)
                               - HEADJIB/LEGJIB/ARMJIB  (trooper parts)
                               - LIZMANARM1/LIZMANLEG1  (lizman parts)
                               - DUKETORSO/DUKELEG/DUKEGUN (duke parts)
                               <amount> determines the amount of guts to fly.

globalsound                  = Play sound that can be heard everywhere in the
                               map.

hitradius <c> <1> <2> <3> <4>= Make an explosion (not the actual animation but
                               just the damage). <c> is the radius. <4> is how
                               much damage is done in first quarter of circle
                               seen from inside to outside.
                               <3> is how much damage is done in second quarter
                               of circle etc.

ifactornotstayput            = (not sure) 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 (ie. health) is
                               lifted into the sky, he doens't fall down to
                               the ground until you spot it!

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, remember?

ifactioncount <number>       = Tests if the actors has display <number> 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.

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 is a nice one because you can use it like
                               this:
                               ifbulletnear
                                 ai AIRUNAWAYFROMBULLET
                               Okay, maybe you don't understand this yet, but
                               I'll explain it later. For now, let's say this
                               code means:
                               If there is a bullet nearby then go into another
                               ai function that makes the actor runaway with high
                               speed (fleeenemy aifunction).


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
                               about this one though.

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

ifceilingdistg <num>         = Tests if the distance to the ceiling is greater
                               than <num>

ifceilingdistl <num>         = Tests if the distance to the ceiling is less
                               than <num>


ifcount <num>                = 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 <num>           = Same as 'ifceilingdistg' but now for the floor.

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

ifgotweaponce <num>          = Seems to test if a player has a particular weapon.
                               The weapon tested would be the current actor.
                               This code would logicaly only appear in weapon
                               actors such as RPGSPRITE.
                               I'm not sure what the <num>'s use is. The values
                               passed in the real CONs where 0 and 1. (?)

ifhitspace                   = Checks if duke 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 <num>                = Tests if the distance between the floor and
                               the ceiling at the actor's location is less than
                               <num>.

ifinspace                    = Checks if current player is in space. 'space'
                               means when the floor/ceiling is parralaxed and
                               the texture is one of the space-textures.

ifinwater                    = Tests if the current actor is in the water.

ifinouterspace               = Tests if the current actor is in outer space?

ifonwater                    = Same as 'ininwater', but then for 'on' the water.

ifmove <name>                = Tests if variable <name> is greater than 0. (not sure)

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 the current
                               actor is equal to <actor>


ifspritepal <num>            = Tests if the palette of the current actor is
                               equal to <num>

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 parralaxing on!

ifp  <type>                  = Tests if the player (when I say player I always
                               mean Duke, but you knew that, right?) is doing
                               <type> where type can be:

                               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 cur. actor?
                               pwalkingback = Duke is walking backwards
                               prunningback = Duke is running backwards
                               pkicking     = Duke is kicking (ass)
                               pshrunk      = Duke is a smurf (shrunken)
                               pjetpack     = Duke is flying (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 exterminated
                               pfacing      = Duke is facing the current actor

                               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 <num>             = Tests if the players health is less than
                               <number>.

ifphealthg <num>             = 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> where item can
                               be:
                               - GET_STEROIDS
                               - GET_HEATS
                               - GET_BOOTS
                               - GET_SHIELD
                               - GET_SCUBA
                               - GET_HOLODUKE
                               - GET_JETPACK
                               - GET_FIRSTAID
                               - GET_ACCESS (when using this the amount seems
                                             to be a bitlist of cards we have
                                             0 = no cards 1 = blue card etc...)


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

ifrnd <num>                  = This is a randomize function. <num> is the
                               chance you give it to be true. If <num> is
                               256 it wil be always true and 128 50% of the
                               times. If you want less chance than 1/256 you
                               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 <num>             = Tests if current actor has <num> strength left.

ifwasweapon                  = Tests what weapon the actor has been hit by.

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

killit                       = Removes the current actor from the map. The
                               won't be called anymore.

lotsofglass <amount>         = Animate glass that breaks as if a window
                               has broken. <amount> determines the ehhh...
                               amount of glass. 30 seems to be a reasonable
                               value.

mail                         = Spawn some mail?

mikesnd                      = Plays the microphone sound...

money <num>                  = Spawns <num> dollar bills.

move <name> <v1> <v2>        = Give <name> a value of <v1> and a optional
                               value of <v2>. When the variable is used to
                               define the speed of an actor the second
                               variable is used for vertical speed. This
                               way you can simulate a character to use a
                               jetpack. I've also seen <v1> and <v2> to
                               be given 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 automaticly 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                       = nullop 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 where you 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 <begin> <end> <del>  = Change palette to color <begin> and then to
                               <end> and then back to normal again (I think?).
                               0 or 32 = Green
                               16      = Red

paper                        = Spawn some paper?

pstomp                       = Player will look down and step on the near
                               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 <num>                  = Print quote <num> 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 exectuted.
                               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 weapons are defined in USER.CON.
                               The direction in which the actor shoots is de-
                               termined 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.
                               Some of the weapons are (these names are also used
                               for ifwasweapon):
                               SHRINKSPARK,
                               SHOTGUN,
                               RPG,
                               CHAINGUN,
                               FREEZEBLAST,
                               KNEE,
                               SPIT,
                               FIRELASTER,
                               HEAVYHBOMB,
                               BOUNCEMINE,
                               MORTER,
                               DEVISTATORBLAST and
                               TRIPBOMB.

sizeat <x> <y>               = Makes the current actor <x> times smaller in
                               x-direction and <y> times smaller in y-direction.
                               The difference between sizeat and sizeto is that
                               sizeat makes the change immediatly while sizeto
                               resizes the actor graduatly.

sizeto <x> <y>               = 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 soundnumbers are defined in
                               USER.CON.

soundonce <soundnum>         = I think when using this sound, it will not
                               be activated again until it is finished.

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
                               while blur. This effect can be seen when
                               an actor is shrinking or a player is on
                               steroids.

spritepal <num>              = Changes palette number of sprite. Legal values
                               are:
                               1  = Blue
                               4  = Dark
                               6  = Night vision Green
                               7  = Yellow (sort of)
                               8  = Green
                               10 = Red
                               19 = Red as a tomato
                               22 = Almost normal

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 <num>               = This function changes the strength of the current
                               actor in <num>

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

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


--------------------------------------------------------------------------
  2.8   Predefined states
--------------------------------------------------------------------------

Here's a list of states that are already defined in GAME.CON. You can
ofcourse alter these but here's a list of some of them (call these
state like this: 'state <name>') :

- genericshrunkcode
  Shrink actor and stomp if within correct distance

- blimbhitstate
  Make explosion. Spawn debris, kill actor and some other stuff...

- rats
  Generate some rats.

- headhitstate
  Gets called when player is being hurt bad.

- burningstate
  Lites the current actor on fire.

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

- burningbarrelcode
  Code for a burning barral (duh!)

- get_code
  Gets an item and prepares it for respawn if neccesary.

- randgetweapsnds
  Plays a random sound when called such as 'Groovy' or 'Come get some' etc.

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

- respawnit
  Respawns the item in multiplayer game.

- firestate
  Updates flames and checks if duke is burning himself etc.

- jib_sounds
  Plays one of those nice sound like 'What a mess' or 'Let god sort them out'.

- standard_jibs
  Spawns some random bodyparts.

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

- killme
  Lets woman say "kiiillll meeee...." when duke hits space near her.

- tipme
  Lets duke give woman a dollar bill and say 'Wanna dance' or 'Shake it baby'.

- troop_body_jibs
  Spawns some trooper body parts.

- liz_body_jibs
  Spawns some lizard body parts.

- delete_enemy
  Deletes the current actor (removes it from the map).

- standard_pjibs
  Spawns some duke body parts.

Ok, that's it for now.

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

--------------------------------------------------------------------------
  3.1   Example 2: Make the atomic health sprite pulsating
--------------------------------------------------------------------------

Okay, we're gonna make the atomice health sprite pulsate between
visibility and invisibility graduatly. Ought to look pretty cool!

(under construction... sorry)

--------------------------------------------------------------------------
  3.2   Example 2: Make your own Duke Bot
--------------------------------------------------------------------------

The example in the last couple of versions of this FAQ was getting a
little complex for some of you guys. It even had some huge bugs in
it. But here's a new example and I'm keeping it as clear as possible.
We're gonna try to create a new Duke character. This character will
eventually do the following:

 - when at a distance he will either fire some rockets or
   run up to you

 - when near he will shoot a shrinker ray at you

 - when you're shrunken he'll stomp you

 - when you shrink him he will shrink
   when you freeze him he will freeze
   when you kill him he will die

 - when he's hit he'll yell or shoot an RPG :-)

 - when you shoot at him he will flee

Ok, but how would we go about this. First we need to replace a character
with our new character. I think our PIGCOP will do fine.
Now remove all the PigCop code. These are the lines
'action APIGWALK ...' to the line just before 'action ABOSS1WALK ...'.
I also recommend creating a one roomed sector with just one pigcop
in it so you can check the code out easy.
Whenever you see this: '*CHECK*' you can check the code out in your map.

First we're gonna define the basics of our character. We need to set up
an action group of Duke standing:

action DUKESTAND     -595  1 5 1 1

Since the PIGCOP standing sprite is tile number 2030 and the Duke standing
sprite is 1405. We need to use -595 since all the sprites must be relative
to 2000 (PIGCOP).

And we need the main actor code ofcourse:

define DUKESTRENGTH 200

actor PIGCOP DUKESTRENGTH DUKESTAND faceplayer
// Drop the character until it hits a surface.
fall

enda

*CHECK*

Now we want him to go look for us so we'll have to define a sprite group
(action) of duke running.

action DUKERUN -575 4 5 1 10

and a speed at which he runs:

move DUKERUNSPEED 240

And NOW we need to define ourselfs an AI function of a duke how is looking
for us:

ai AIDUKESEEKPLAYER DUKERUN DUKERUNSPEED seekplayer

Now we need to add the following code to the actor code (right after 'fall')

// Are we still standing?
ifaction DUKESTAND
  // Yep, so now start looking for player
  ai AIDUKESEEKPLAYER

*CHECK*

Now duke runs, but strangly enough not to you. That's because we need to
call the ifcansee { } function? to update dukes vision. You can place the
ifcansee { } right after the fall line in the actor code and then check
again. Remove this code afterwards however since we don't need it to be
_there_. Now we're gonna create a state (put this, like actions, ai's and
move's outside the actor code)...

state dukeseekplayer
ends

... with no code in it yet. This state needs to be called whenever we are
in the seeking ai. So put this in the actor code _after_ the 'ai AIDUKE
SEEKPLAYER' line:

ifai AIDUKESEEKPLAYER
   state dukeseekplayer

So now if we are in the seekplayer ai the dukeseekplayer will be called!

Now we're gonna add the following: if dukes near the player he'll start
to fire shrinker rays. Put this code into the dukeseekplayer state:

// Can we see the player
ifcansee
  {
  // Is player near?
  ifpdistl 5000
    // Can we shoot the target?
    ifcanshoottarget
       // Go into shooting ai
         ai AIDUKESHOOTFROMCLOSE
  }

So you'll see we'll have to define a new AI function AIDUKESHOOTFROMCLOSE.

ai AIDUKESHOOTFROMCLOSE DUKERUN DUKERUNSPEED faceplayer

And we'll need to add this part to the actor code after the 'state dukeseek...'
line:

ifai AIDUKESHOOTFROMCLOSE
   state dukeseekplayer


So you see that we use the same state when he shooting. Obviously we need
something in the dukeseekplayer state to identify wether duke is seeking
or shooting. Add this before the 'ifcansee' line in the duke seekplayer
state:

// Are we shooting?
ifai AIDUKESHOOTFROMCLOSE
  {
  // Can we see him?
  ifcansee
    {
    // Is he still close?
    ifpdistl 6000
      {
      // Can we shoot our target?
      ifcanshoottarget
        // Only shoot every 10 counts
        ifcount 10
          {
          resetcount
          shoot SHRINKER
          sound SHRINKER_FIRE
          }
      }
      else
      // No we are not close anymore so seek him.
      ai AIDUKESEEKPLAYER
    }
    else
    // We can't see him anymore so seek him.
    ai AIDUKESEEKPLAYER
  // We don't want to rest of the state to be executed so
  // directly return
  break
  }

*CHECK*

Wooow. We got ourselfs a mad duke running after us shooting shrinker
rays. Isn't that great. But hey, when we're shrunken he keeps shooting
at us? Ok, lets fix that. We want duke to go into another ai function
when he has shrunken us.

ai AIDUKEWANTTOSTOMP DUKERUN DUKERUNSPEED seekplayer

Now add this code to the main actor code right before the 'ifai
AIDUKESEEKPLAYER' line:

ifp pshrunk
  {
  // Are we already wanting to stomp?
  ifai AIDUKEWANTTOSTOMP
    {
    }
    else
    // No so do it.
    ai AIDUKEWANTTOSTOMP
  }

and add the following after the 'ifai AIDUKESHOOTFROMCLOSE state
dukeseekplayer' line:


ifai AIDUKEWANTTOSTOMP
   {
   // If he's already dead we've got nothing to do.
   ifp pdead
     {
     }
     else
     state dukewanttostomp
   }

Now we're gonna define the state:

state dukewanttostomp

// Is he still shrunken?
ifp pshrunk
  {
  // Can we see him?
  ifcansee
    {
    // Is he near enough to stomp?
    ifpdistl SQUISHABLEDISTANCE
       {
       // Kill him by subtracting 400 health (ought to be enough)
       addphealth -400
       // A nice sound
       sound SQUISHED
       // Some flying body parts
       state standard_pjibs
       state standard_pjibs
       // Yet another nice sound
       sound DUKE_KILLED4
       }
    }
  }
  // He is not shrunken anymore
  else
  ai AIDUKESEEKPLAYER

ends

Ok, only this time, and this time only, I'll give you all we got now:

// --------------

define DUKESTRENGTH 200

action DUKESTAND     -595 1 5 1 1
action DUKERUN       -575 4 5 1 10

move DUKERUNSPEED 240

ai AIDUKESEEKPLAYER DUKERUN DUKERUNSPEED seekplayer
ai AIDUKESHOOTFROMCLOSE DUKERUN DUKERUNSPEED faceplayer
ai AIDUKEWANTTOSTOMP DUKERUN DUKERUNSPEED seekplayer


state dukeseekplayer

ifai AIDUKESHOOTFROMCLOSE
  {
  ifcansee
    {
    ifpdistl 6000
      {
      ifcanshoottarget
        ifcount 10
          {
          resetcount
          shoot SHRINKER
          sound SHRINKER_FIRE
          }
      }
      else
      ai AIDUKESEEKPLAYER
    }
    else
    ai AIDUKESEEKPLAYER
  break
  }

ifcansee
  {
  ifpdistl 5000
    ifcanshoottarget
       ai AIDUKESHOOTFROMCLOSE
  }


ends

state dukewanttostomp

ifp pshrunk
  {
  ifcansee
    {
    ifpdistl SQUISHABLEDISTANCE
       {
       addphealth -400
       sound SQUISHED
       state standard_pjibs
       state standard_pjibs
       sound DUKE_KILLED4
       }
    }
  }
  else
  ai AIDUKESEEKPLAYER

ends

actor PIGCOP MAXPLAYERHEALTH DUKESTAND faceplayer
fall

ifaction DUKESTAND
  ai AIDUKESEEKPLAYER

ifp pshrunk
  {
  ifai AIDUKEWANTTOSTOMP
    {
    }
    else
    ai AIDUKEWANTTOSTOMP
  }

ifai AIDUKESEEKPLAYER
   state dukeseekplayer

ifai AIDUKESHOOTFROMCLOSE
   state dukeseekplayer


ifai AIDUKEWANTTOSTOMP
   {
   ifp pdead
     {
     }
     else
     state dukewanttostomp
   }


enda

// --------------

*CHECK*

Well, he shoots and he kills. That's my kind of duke. Now, we're gonna
add the part were he shoots rockets from a distance. Yeah!

Ok, this code needs to be put in the dukeseekplayer state. In this state
we test if the distance is near (ifpdistl 5000). If it's true (he IS near)
then - if we can shoot the target - we go into the AIDUKESHOOTCLOSE ai
function. What we need to do is add an else like this:

The code was:

ifcansee
  {
  ifpdistl 5000
    ifcanshoottarget
       ai AIDUKESHOOTFROMCLOSE
  }


the code gets to be:

ifcansee
  {
  ifpdistl 5000
    {
    ifcanshoottarget
       ai AIDUKESHOOTFROMCLOSE
    }
    else
    {
    // Once in a while
    ifrnd 1
      {
      // start shooting rockets
      ai AIDUKESHOOTROCKET
      break
      }
    }

  }

Yep. A new ai function:

move DUKESLOWSPEED 50

action DUKECRAWL -509 3 5 1 30

ai AIDUKESHOOTROCKET DUKECRAWL DUKESLOWSPEED faceplayer

And now add this code after the 'ifai AIDUKESHOOTFROMCLOSE
state dukeseekplayer' line:

ifai AIDUKESHOOTROCKET
  state dukeshootrocket

Now we'll define the state:

state dukeshootrocket

// Can we see duke?
ifcansee
  {
  // Is he still far away?
  ifpdistg 8000
    {
    // Can we shoot the target?
    ifcanshoottarget
      {
      // Only shoot once in the 20 counts
      ifcount 20
        {
        // Start counting all over again.
        resetcount
        shoot RPG
        sound RPG_SHOOT
        }
      }
    }
    // No he's getting closer
    else
    ai AIDUKESEEKPLAYER

  }
  // Can't see him anymore so go find him.
  else
  ai AIDUKESEEKPLAYER

ends

Wooow. When at a distance, if some cases he will start shooting RPG's.
What a guy! Now we're gonna teach him to dodge bullets when they're
near.

So yet another ai function:

ai AIDUKEDODGEBULLET DUKECRAWL DUKERUN fleeenemy

Put this is the main actor code before 'ifp pshrunk':

// Is a bullet nearby?
ifbulletnear
  // Yep, so evade it.
  ai AIDUKEDODGEBULLET

And put this also in the actor code but after 'state dukeshootrocket':

// If evasion ai is active
ifai AIDUKEDOGDEBULLET
  {
  // Are we done (use evasion for 5 counts, ought to be enough)
  ifcount 5
    {
    // We're done. So go back to seekplayer
    ai AIDUKESEEKPLAYER
    // Reset counter
    resetcount
    // We're done.
    break
    }
  }


Wow. He evades rockets and stuff. Groovy. Ok, now we have given him a
chance to survive so we're gonna write to stuff that gets executed when
he is hurt and/or killed. First we need to define an ai and an action
group of duke getting hurt!

action DUKEPAIN -489 1 1 1 10

// DUKESTOPPED = 0
move DUKESTOPPED

ai AIDUKEBEINGHURT DUKEPAIN DUKESTOPPED faceplayer

Now add this code to the main actor code right before the 'ifbulletnear'
code:

ifai AIDUKEBEINGHURT
  {
  state dukebeinghurt
  break
  }

ifhitweapon
  {
  ai AIDUKEBEINGHURT
  break
  }

Now here's the dukebeinghurt state:

state dukebeinghurt

ifdead
  {
  // Play nice sound
  sound SQUISHED
  // Play a death sound
  ifrnd 128
    sound DUKE_KILLED4
    else
    sound DUKE_DEAD

  // Some body parts
  state standard_pjibs
  state standard_pjibs

  killit
  }
  else
  {
  // No he wasn't dead yet so play a randomly chosen
  // hurt sound.
  ifrnd 64
    sound DUKE_LONGTERM_PAIN2
    else
    ifrnd 64
      sound DUKE_LONGTERM_PAIN3
      else
      ifrnd 64
        sound DUKE_LONGTERM_PAIN4
        else
        ifrnd 64
          sound DUKE_LONGTERM_PAIN5

  }

// After two frames go back to seeking mode again.
ifactioncount 2
  ai AIDUKESEEKPLAYER

ends


Ok, if duke gets shot with a gun he also explodes. So what? The dying
animation doesn't work because this is _actually_ a pigcop. And pigcops
die differently. Sorry. Now you can kill him easily by just shooting
at him. I want him to - sometimes - shoot back with a RPG if he
is being hit.

This needs to be done in the hurt part where all the ifrnd 64's are.
The code now is:

  else
  {
  // No he wasn't dead yet so play a randomly chosen
  // hurt sound.
  ifrnd 64
    sound DUKE_LONGTERM_PAIN2
    else
    ifrnd 64
      sound DUKE_LONGTERM_PAIN3
      else
      ifrnd 64
        sound DUKE_LONGTERM_PAIN4
        else
        ifrnd 64
          sound DUKE_LONGTERM_PAIN5

  }

and the code gets to be:

  {
  // No he wasn't dead yet so play a randomly chosen
  // hurt sound.
  ifrnd 64
    sound DUKE_LONGTERM_PAIN2
    else
    ifrnd 64
      sound DUKE_LONGTERM_PAIN3
      else
      ifrnd 64
        sound DUKE_LONGTERM_PAIN4
        else
        ifrnd 64
          sound DUKE_LONGTERM_PAIN5

  // 25% chance he shoots when being hurt
  ifrnd 64
    {
    // Only shoot every 3 counts.
    ifcount 3
      {
      resetcount
      shoot RPG
      sound RPG_SHOOT
      }
    }

  }

Ok, now we only need two things until we're done. The possibility to shrink
him and the possibility to freeze him. You're on your own from now on...
... so figure this out yourself. Check the code of other actors to see how
it's done. If you still have any questions you can always mail me at
antiwin@worldonline.nl


--------------------------------------------------------------------------
  4.1  DEFS.CON (overview)
--------------------------------------------------------------------------

DEFS.CON is the CON file in which all defines are done. This way
you can name a tile or sound by name instead of number. It is
included by GAME.CON

--------------------------------------------------------------------------
  4.2  USER.CON (overview)
--------------------------------------------------------------------------

In USER.CON all sorts of defines are done. All levels and sounds are
defined here. Also other game effects like respawning time etc. are
declared here. It is included by GAME.CON

--------------------------------------------------------------------------
  4.3  GAME.CON (overview)
--------------------------------------------------------------------------

This is the main CON file. It gets compiled first. It includes DEFS.CON
and USER.CON first. In this CON file all the actor code is located. You
could put actor code in the USER.CON but it looks better if you keep it
all in GAME.CON.

--------------------------------------------------------------------------
  5.1  What *I* would like to know
--------------------------------------------------------------------------

Here's a list of things I would like to know. So if you do, _please_
mail me.

 - Is there someone who would like to help me maintain this FAQ? Knowledge
   of CON hacking is required ofcourse.
 - Why is 'ifcansee' needed to let seekplayer and other ai function work
   properly?
 - Explenation of some of the ai functions.
 - What does ifnotmoving do in fact? Is this neccesary due to a bug
   in the ai functions?

--------------------------------------------------------------------------
  5.2  Contributers/Thank you's
--------------------------------------------------------------------------

I want to thank:

 - Reptile ( reptile@ <http://> )
 - Linkers ( linkers@, <http://> )

for introducing me to Duke Nukem 3D as it is the funest game I've ever
seen (yeah, that also means more fun than Quake!).

--------------------------------------------------------------------------
  5.3    Update and info
--------------------------------------------------------------------------

An update of this FAQ will come within a week of release. I hope all of
you guys will send me lots of mail within that week, so I can make the
FAQ better. Also, I want to say, that even if it sounds that I know every-
thing, I know I don't. Please don't blame me for saying things that are
incorrect. The right thing to do is to mail me and correct me. It will be
corrected in the FAQ right away. Also there are some things, I'd like to
know more about. So if you have any info and CON hacking, don't hesitate
to mail me at antiwin@worldonline.nl

--------------------------------------------------------------------------
  5.4    Where to get this FAQ
--------------------------------------------------------------------------

I hope you can soon download this FAQ from many Duke 3D sites. An update
of this FAQ is posted _at least_ once a week in the following newsgroups:
alt.games alt.games.apogee alt.games.duke3d