
                    RISEN3d Engine Definitions Reference
                   ======================================
                                  V220


---------------------------------------------------------------------------
STANDARD DED FILES
---------------------------------------------------------------------------

Risen3D deds are included in the main Game distribution and are in the
"Defs" folder.  This must not be changed, edited or renamed.

These files are specific to Risen3D as is the directory structure
and should only be used with v220. 

For v220 they are;

Defs\Base\CoreEffects.ded
Defs\Base\FinalesDoom.ded
Defs\Base\FinalesPlut.ded
Defs\Base\FinalesTNT.ded
Defs\Base\gndText.ded
Defs\Base\Maps.ded
Defs\Base\R3DFlags.ded
Defs\Base\R3DSprites.ded
Defs\Base\R3DStates.ded
Defs\Base\R3DThings.ded
Defs\Base\Text.ded
Defs\Base\Values.ded


Defs\Model\Decorations.ded
Defs\Model\FlameModels.ded
Defs\Model\Grenade.ded
Defs\Model\HudWeapons.ded
Defs\Model\Items.ded
Defs\Model\Monsters.ded
Defs\Model\Players.ded
Defs\Model\Splashes.ded
Defs\Model\Weapons.ded
Defs\Model\Addon\Chaingun.ded
Defs\Model\Addon\ExtraFX.ded

Other directories will be included in the Model directory for alternative
weapons or soldiers.  This is done automatically when installing packs
available from the Risen3D website.

The flag types can be found in R3Dflags.ded.  Many of the mf2_ and all of
the mf3_ types are specific to Risen3D


---------------------------------------------------------------------------
GENERAL SYNTAX
---------------------------------------------------------------------------
Elements of a DED file:

* Comments

  There are two kinds of comments: single-line and multi-line. Single line
  comments begin with a hash character (#) and continue until end of line.
  The parser will skip everything on the line after the # character. Multi-
  line comments begin with #> and continue until <# is found. An example:

      #> The comment begins...
      And continues
      ...and ends here <#

* Header block

  Use of the Header block is optional but it is recommended that you at
  least use a version declaration:

      Header { Version = 5; }

* Directives

* Definition blocks

* Attributes

  The "Copy" attribute can be replaced with an asterisk (*).

* Keys

* String values

  Strings begin and end in double quotation marks ("). If newline
  characters are found inside a string (the string has been divided into
  multiple lines) the newline and all following whitespace are skipped, and
  the actual string continues from the first non- whitespace character that
  follows.


---------------------------------------------------------------------------
DIRECTIVES
---------------------------------------------------------------------------
...........................................................................

Include "Other.ded";
    # The Include directive causes the parser to read the given DED
    # file. Included files are read *after* the file, which they were
    # included from.

IncludeIf <Not> -option "Other.ded";
    # The given DED file is included if the option "-option" is (not)
    # found in the command line.

SkipIf <Not> -option;
    # The rest of the file is skipped if the option "-option" is (not)
    # found in the command line.

ModelPath "MD2\Game\Item";
    # The ModelPath directive appends a new path to the list of model
    # search paths. NOTE: It should be noticed that this directive has
    # no scope: it affects all the definitions that come before and
    # after it. Also, be careful with backslashes. Since they are used
    # as escape characters in strings you can't for example do this:
    # "MD2\Game\Path\". That would mean the last character of the path
    # is " but the string itself doesn't end. You can use forward
    # slashes instead of backslashes.

...........................................................................


---------------------------------------------------------------------------
THING DEFINITIONS
---------------------------------------------------------------------------
...........................................................................

Thing
{
    ID = "";
    DoomEd number = 0;

    Name = "";
        # The real name of this thing, for example "Bag of Holding".
        # Currently not used by the engine.

    Spawn state = "";
    See state = "";
    Pain state = "";
    Melee state = "";
    Missile state = "";
    Crash state = "";
    Death state = "";
    Xdeath state = "";
    Raise state = "";
    See sound = "";
    Attack sound = "";
    Pain sound = "";
    Death sound = "";
    Active sound = "";
    Reaction time = 0;
    Pain chance = 0;
    Spawn health = 0;
    Speed = 0.0;
    Radius = 0.0;
    Height = 0.0;
    Mass = 0;
    Damage = 0;
    Flags = "";
    Flags2 = "";
    Flags3 = "";
    Misc1 = 0;
    Misc2 = 0;
    Misc3 = 0;
    Misc4 = 0;
}

...........................................................................


---------------------------------------------------------------------------
STATE DEFINITIONS
---------------------------------------------------------------------------
...........................................................................

State
{
    ID = "";
        # Identifier of this state.

    Flags = "";
    Sprite = "";

    Frame = 0;
        # Sprite frame. OR with 0x8000 (32768) to make fullbright.

    Tics = 0;

    Action = "";
        # Name of the action function of this state.

    Next state = "";
    Misc1 = 0;
    Misc2 = 0;
    Misc3 = 0;
}

...........................................................................


---------------------------------------------------------------------------
SPRITE DEFINITIONS
---------------------------------------------------------------------------
...........................................................................

Sprite
{
    ID = "";
        # Name of the sprite. Must be four characters long. Sprite
        # frame lump names always begin with a sprite ID.
}

...........................................................................


---------------------------------------------------------------------------
LIGHT DEFINITIONS
---------------------------------------------------------------------------
The engine usually calculates the properties of dynamic lights based on the
sprite frame of the light source. Any zero values in the Light definition
will be replaced by these automatic calculations (zero is the default for
all keys).
...........................................................................

<Copy> Light
{
    # If "Copy" is found all the data of the previous definition is
    # copied to this one as defaults. For the first definition in a
    # file "Copy" has no effect.

    State = "";
        # The State with which the light properties defined here will
        # be used.

    Flags = "";
        # lgf_nohalo: No lens flare (halo) is rendered.

    X Offset = 0.0;
        # In pixels, offset from the center of the source. The offset
        # is parallel with the view plane.

    Y Offset = 0.0;
        # In pixels, offset from the top of the source object.

    Size = 0.0;
        # Size (strength) of the light. Should be between 0 and 1.

    Red = 0.0;
        # Red color component (0-1).

    Green = 0.0;
        # Green color component (0-1).

    Blue = 0.0;
        # Blue color component (0-1).

    Color { 0.0 0.0 0.0 };
        # Sets all three color components at the same time.
}

...........................................................................


---------------------------------------------------------------------------
DETAIL TEXTURE DEFINITIONS
---------------------------------------------------------------------------
General detail texture strength, scaling and maximum distance can modified
with the "detail" console command. One Detail definition can be used to
assign a detail texture to one wall texture and/or one flat picture.
...........................................................................

<Copy> Detail
{
    # If "Copy" is found all the data of the previous definition is
    # copied to this one as defaults. For the first definition in a
    # file "Copy" has no effect.

    Wall = "";
        # Name of the wall texture which this detail texture should be
        # associated with.

    Flat = "";
        # Name of the flat which this detail texture should be
        # associated with.

    Lump = "";
        # Lump name of the detail texture (e.g. "DTLROUGH"). This must
        # be a 64x64, 128x128 or 256x256 raw image with one color
        # component (a black and white image). This means the size of
        # the lump can be either 4096, 16384 or 65536 bytes.

    Scale = 1.0;
        # Relative scaling for the detail texture. Actual scaling is
        # calculated with (Scale)*(common-scaling-factor). The default
        # value for the common scaling factor is 4 (which means one
        # world unit corresponds four detail texture pixels).

    Strength = 1.0;
        # Relative intensity factor. Actual strength is calculated
        # with (Strength)*(common-strength-factor). The default value
        # for the common strength factor is 0.5.

    Distance = 0.0;
        # Maximum distance at which the detail texture is visible. If
        # left at zero, the common maximum distance is used (default:
        # 256). Smaller maximum distances may cause problems with
        # floors and ceilings, where big polygons cause inaccuracies
        # in the calculation of eye -> vertex distance.
}

...........................................................................


---------------------------------------------------------------------------
GENERATOR DEFINITIONS
---------------------------------------------------------------------------
A particle generator must always be triggered somehow to be spawned. There
are four types of triggers available: State, Type, Flat and Map. The
trigger also determines the generator's source, from which the generator's
particles seem to originate. A generator must have a source to be able to
create new particles. If the source of a generator is destroyed before the
generator dies, the only result will be that no new particles are created.
Any existing particles created prior to the removal of the source will live
on.

State triggering means that the generator is spawned when any mobj enters
the state the generator has been associated with. The mobj in question will
become the source of the generator. State triggering is especially useful
with "one time" effects such as explosions. State triggering should be
avoided with mobjs that have a loop of states (if the gnf_spawn flag is not
used). This can lead to generators being spawned more frequently than
necessary.

All Type triggered generators are spawned at the beginning of a level. Each
Type triggered Generator definition gets its own particle generator entity.
Type triggering makes the generator multi-sourced: all mobjs in the level
with one of the types associated with the generator will act as particle
sources. The effect is similar to having a separate generator for each
mobj. Note, however, that you need to allocate a fairly large number of
particles in the definition since all the mobjs use the same generator.

Flat triggering works a bit differently. The level is periodically checked
for any planes with the specified flat as texture (floors and ceilings). A
generator is spawned for all planes that match the associated flat. The
sector to which the plane belongs will become the source of the generator.
The origin of the particles can be the ceiling or floor plane, or the space
in between. The default behaviour can be modified using the gnf_floor,
gnf_ceiling and gnf_space flags. Each plane can have only one generator,
i.e. each sector can have up to two generators.

Map triggered generators are all spawned in the beginning of a level, but
only if the level has a map ID that matches the generator's. Map triggered
generators use the Center key to define their origin because they haven't
got an object as a source. The Center is interpreted as world coordinates
(X,Y,Z). When using map triggered generators it's probably best to set the
Max age and Spawn age keys to -1, to allow the generator to operate
indefinitely.

There is a limit to the number of active particle generator entities in the
level (currently 96). If the maximum number is reached, existing non-static
generators will be destroyed to make room for any new generators.
...........................................................................

<Copy> Generator
{
    State = "";
        # Particle generators can be either State, Flat or Type
        # triggered. Whenever a mobj is set to this state, a new
        # particle generator is spawned. If the gnf_spawn flag is set,
        # the generator is only spawned when the source mobj itself is
        # being spawned; handy if the mobj has a loop of states and
        # the generator should only be spawned when the state is first
        # set.

    Flat = "";
        # Makes this a Flat triggered generator. Each plane with the
        # given flat receives its own generator. The gnf_* flags can
        # be used to control where the particles are actually spawned.

    Mobj = "";
        # Makes this a Type triggered generator. The value must be a
        # defined thing ID (e.g. "PLAYER"). All Type triggered generators
        # are spawned in the beginning of a level, and they create 
        # particles using all mobjs of the given type as sources. Use the 
        # gnf_static flag to prevent the generator from being removed by 
        # later generators (could happen when the maximum number of 
        # generators is reached).

    Alt mobj = "";
        # Alternate mobj type for Type triggered generators.

    Damage mobj = "";
        # Makes this a Damage triggered generator. They are spawned when a 
        # mobj of the specified type receives damage. The initial movement
        # direction is calculated from the positions of the mobjs involved 
        # in the operation, so that positive speed values will make the
        # particles move away from the inflictor (in the direction of the 
        # damage). 
        #
        # NOTE: Damage triggered particle generators currently do not work
        #       on the clientside (netgames and demos).

    Map = "";
        # Makes this a Map triggered generator. The generator is spawned
        # only in the specified map (e.g. "E2M3"). The Center key defines
        # the spawn origin.

    Flags = "";
        # gnf_static: Generator will not be removed until it times
        #       out. Otherwise it might get replaced by newer
        #       generators if there are too many active generators.
        #
        # gnf_srcvel: (State/Type triggered) Particles inherit their
        #       source's velocity (in addition to spawn velocity).
        #
        # gnf_spawn: Generator is only spawned if the source mobj is
        #       being spawned.
        #
        # gnf_blend: Particles of the generator are rendered using
        #       additive blending.
        #
        # gnf_modelonly: The particle generator will only be active
        #       if the source is represented by a 3D model.
        #
        # gnf_floor: (Flat triggered) Particles of the generator will
        #       be created on the floor of the source sector.
        #
        # gnf_ceiling: (Flat triggered) Particles of the generator
        #       will be created in the ceiling of the source sector.
        #
        # gnf_space: (Flat triggered) Particles of the generator will
        #       be spawned at a random height in the sector.
        #
        # gnf_density: (Flat triggered) The "Particles" key specifies
        #       the maximum density of particles per block (128x128)
        #       rather than the maximum number of particles for the
        #       generator.

    Speed = 0.0;
        # Initial speed for new particles.

    Speed Rnd = 0.0;
        # Randomness of initial particle speed (between 0 and 1):
        # 0 = Not random at all.
        # 1 = Randomly scaled between zero and the value of "Speed".

    Vector { 0.0 0.0 0.0 };
        # Initial movement direction for new particles.

    Vector Rnd = 0.0;
        # Randomness of initial particle direction. Random components
        # of the given value are added to "Vector". For example, if
        # "Vector Rnd" is 2, a random vector with components ranging
        # from -2 to 2 is added to "Vector".

    Center { 0.0 0.0 0.0 };
        # (State/Type triggered) An offset to the source coordinates.
        # X = Distance on the XY plane (world units), rotated using
        #     source angle.
        # Y = Source angle offset.
        # Z = Z distance (positive is upwards, world units).
        #
        # (Map triggered) Coordinates of the origin (X, Y, Z).

    Spawn radius = 0.0;
        # Particles will be spawned at a random distance from the center of
        # the source, at a distance of at most this many units. A flat 
        # distribution inside a cube is used if the Min spawn radius is 
        # zero.
 
    Min spawn radius = 0.0;
        # Particles will be spawned at least this many units away from the
        # center of the source. Setting this to a nonzero value will enable
        # the more advanced algorithm for choosing particle spawn 
        # coordinates: a random point is chosen inside a sphere with the
        # radius of Spawn radius, but not closer than Min spawn radius.

    Distance = 0.0;
        # Maximum distance at which the particles of the generator are
        # visible. If zero, there is no distance limitation.

    Spawn age = 0;
        # Number of tics that the generator will create new particles
        # after having been spawned. If -1, the generator will
        # continue creating new particles until destroyed.

    Max age = 0;
        # Maximum generator lifetime, in tics. If -1, the generator
        # will not be destroyed until either replaced by a newer
        # generator or the level ends.

    Particles = 0;
        # Maximum number of particles that the generator can have, or
        # the maximum density of particles per 128x128 block (with
        # Flat triggered generators using the gnf_density flag).

    Spawn rate = 0.0;
        # Number of new particles spawned per game tic. Fractional
        # values are allowed (< 1.0).

    Spawn Rnd = 0.0;
        # Randomness of spawn rate (between 0 and 1):
        # 0 = Not random.
        # 1 = Spawn rate is randomly scaled between zero and the value
        #     of "Spawn rate".

    Presim = 0;
        # Number of tics to "think ahead" when the generator is
        # spawned. Useful for Flat triggered generators that are
        # visible right after starting a level.

    Alt start = 0;
        # Index number of the alternative particle start stage. By
        # default all particles start from stage zero.

    Alt Rnd = 0.0;
        # Randomness of initial particle stage (between 0 and 1):
        # 0   = Default stage (zero) is always used.
        # 0.5 = 50% chance of starting with Alt start.
        # 1   = Always start from Alt start.

    Force = 0.0;
        # Strength of the sphere force that pulls or pushes particles 
        # towards the surface of the sphere. In most cases the value should
        # be less than one.
        
    Force radius = 0.0;
        # Radius of the sphere for sphere force. The force will push or 
        # pull particles to the surface of this sphere, centered around the
        # center of the generator (with the offset specified with Force 
        # origin applied).
        
    Force origin { 0.0 0.0 0.0 };
        # Defines the coordinates for the force sphere in relation to the
        # center of the source.
        
    Force axis { 0.0 0.0 0.0 };
        # The sphere force can also rotate particles around an axis. The 
        # length of the axis defines how strong the rotation is.

    Stage
    {
        # Each generator can have up to 16 particle stages. Each
        # particle will go through the defined stages starting from
        # zero or the alternative start stage.

        Type = "";
            # pt_point: Render particle as a point.
            #
            # pt_line: Render particle as a line. The length of the
            #       line depends on the speed of the particle.

        Tics = 0;
            # Number of tics that the particle will spend in this
            # stage.

        Rnd = 0.0;
            # Randomness of stage tics (between 0 and 1).

        Color { 0.0 0.0 0.0 0.0 };
            # RGBA color of the stage (components between 0 and 1).
            # The fourth component of the color vector is the alpha
            # component: 1 = opaque, 0 = fully transparent.

        Radius = 0.0;
            # Radius of the particle at this stage, in world units.
            # The visible radius is interpolated between the radii of
            # the current stage and the next one.

        Flags = "";
            # ptf_stagetouch: When touching a wall or a plane, the
            #       particle will immediately skip to the next stage.
            #
            # ptf_stagevtouch: Only applies to walls.
            #
            # ptf_stagehtouch: Only applies to planes.
            #
            # ptf_dietouch: Particle will die when it touches a wall
            #       or a plane.
            #
            # ptf_bright: Particle's color is not affected by the
            #       light level of the sector it's in.
            #
            # ptf_flat: When touching a wall or a plane, the particle
            #       is rendered flat against the surface.
            #
            # ptf_vflat: Only applies to walls.
            #
            # ptf_hflat: Only applies to planes.
            #
            # ptf_force: Particle is affected by the sphere force.

        Bounce = 0.0;
            # Determines how 'bouncy' the particle is (0..1):
            # (particles will only collide with walls and planes)
            # 0 = Particle loses all its momentum when it hits
            #     something (in the direction of the collision).
            # 1 = Particle retains all its momentum and continues
            #     moving in the opposite direction after a collision.
            # >1 = Particle gains extra speed in collisions.

        Gravity = 0.0;
            # Determines how strong an effect gravity has on the
            # particle. Normal mobjs have a Gravity factor of 1.0.

        Resistance = 0.0;
            # Air resistance for the particle (between 0 and 1):
            # 0   = Particle moves without friction.
            # 0.5 = Particle loses half of its momentum each tic.
            # 1   = All movement of the particle will stop in one tic.
    };
}

...........................................................................


---------------------------------------------------------------------------
SOUND DEFINITIONS
---------------------------------------------------------------------------
...........................................................................

Sound
{
    ID = "";
    Lump = "";
    Name = "";
    Link = "";
    Link pitch = 0;
    Link volume = 0;
    Priority = 0;
    Max channels = 0;
    Flags = "";

    Ext = "";
    File = "";              # Same as "Ext"
    File name = "";         # Same as "Ext"
        # External sound file. Must be a mono WAV file with no
        # compression. If specified, this sound file will be played
        # instead of the sound data in Lump (if a Lump is defined).
        # Relative paths are interpreted in relation to the base path, so
        # "Sound/Kaboom.wav" becomes "<BasePath>/Sound/Kaboom.wav".
}

...........................................................................


---------------------------------------------------------------------------
MUSIC DEFINITIONS
---------------------------------------------------------------------------
...........................................................................

Music
{
    ID = "";
        # The ID of the song.

    Lump = "";
        # Name of a lump containing a MUS song.

    Ext = "";
    File = "";              # Same as "Ext"
    File name = "";         # Same as "Ext"
        # External music file. Played using FMod. This can either be a
        # file name (e.g. "c:\music\song.mp3") or a CD track (e.g.
        # "cd:8"). Supports many kinds of music files, see
        # http://www.fmod.org/ for details. Relative paths are
        # interpreted in relation to the base path, so "Music/Rock.mp3"
        # becomes "<BasePath>/Music/Rock.mp3".

    CD track = 0;
        # Overrides "cd:" in the Ext key.
}

...........................................................................


---------------------------------------------------------------------------
TEXTURE ENVIRONMENT DEFINITIONS
---------------------------------------------------------------------------
...........................................................................

Texture Environment
{
    ID = "";
        # Identifier of this environment. Must be either "Metal",
        # "Rock", Wood" or "Cloth".

    Texture
    {
        # There can be any number of Texture blocks inside a Texture
        # Environment definition.

        ID = "";
            # Name of a wall texture (e.g. "STARTAN3").
    }
}

...........................................................................


---------------------------------------------------------------------------
MAP INFO DEFINITIONS
---------------------------------------------------------------------------
...........................................................................

Map Info
{
    ID = "";
        # Map identifier. Could be "ExMy" or "MAPxy" depending on the
        # game. Example: if this map info is meant for the first map
        # of the second episode, the ID is "E2M1". If the ID is "*"
        # (asterisk), this definition will be used for all maps that
        # don't have a definition of their own.

    Name = "";
        # Name of the map. Displayed e.g. in the automap and in the
        # console when the map is loaded.

    Author = "";
        # Author of the map. Displayed e.g. in the console when the
        # map is loaded.

    Flags = "";
        # mif_fog: Enable fog in the map.

    Music = "";
        # Identifier of the song to play during this map. Notice that
        # this is the identifier of the Music definition, not the
        # actual MUS lump found in a WAD file.

    Par time = 0.0;
        # Par time of the map, in seconds.

    Fog color R = 0.0;
        # Red color component (0-1) of the fog used in the map.

    Fog color G = 0.0;
        # Green color component (0-1) of the fog used in the map.

    Fog color B = 0.0;
        # Blue color component (0-1) of the fog used in the map.

    Fog start = 0.0;
        # (Linear fog) Fog start distance, in world units.

    Fog end = 0.0;
        # (Linear fog) Fog end distance, in world units.

    Fog density = 0.0;
        # Used in exponential(2) fog mode.

    Ambient light = 0.0;
        # Minimum light level (0-1) of all sectors in the map.

    Gravity = 1.0;
        # Gravity in the map.

    Sky height = 0.666667;
        # Height of the sky sphere (0-1). The real height is an angle
        # calculated with Pi/2 * (sky height), which means if the sky
        # height is 1, the sphere covers the whole sky.

    Horizon offset = 0.0;
        # Angle offset to sky vertices, in radians. Negative angles
        # move the horizon downwards.

    Sky Layer 1
    {
        Flags = "";
            # slf_enable: Enable layer. By default the layer is
            #       disabled and will not be rendered.
            #
            # slf_mask: Layer texture's color zero should be masked.

        Texture = "";
            # Name of the texture to use for this layer.

        Offset = 0.0;
            # A horizontal offset applied to the texture coordinates
            # of the layer.

        Color limit = 0.0;
            # Specifies how small an intensity (0-1) the sky fadeout
            # color (top line of the texture) can have before the
            # fadeout color is reduced to black.
    };
    Sky Layer 2
    {
        Flags = "";
        Texture = "";
        Offset = 0.0;
        Color limit = 0.0;
    };
}

...........................................................................


---------------------------------------------------------------------------
FINALE DEFINITIONS
---------------------------------------------------------------------------
The Finale definition is used to define intros, interludes and finale
animations. All of these are called "finales" in this reference. The
finales of the original DOOM, Heretic and Hexen typically have a tiled flat
as the background and text that is slowly typed onto the screen.
...........................................................................

Finale
{
    Before = "";
        # Identifier of the map before which this finale should be
        # played. The precise form of the identifier depends on the
        # Game, but the two commonly used ones are "ExMy" and "MAPxy",
        # where "x" and "y" denote episode and map numbers; "E2M3".

    After = "";
        # Identifier of the map after which this finale should be
        # played. Normally it's useful to only use either one of the
        # Before and After keys, though both can be set at the same
        # time.

    Game = 0;
        # Game selector. Currently only used by jDoom to separate
        # Plutonia (Game=1) and TNT (Game=2) from Doom II (Game=0).

    Script { };
        # An InFine script that defines what the finale does. The same
        # parsing rules are used when reading the script and the DED
        # file itself, so for instance strings can be split onto
        # multiple lines (see Text definitions). See the InFine
        # Scripts reference for more information.
}

...........................................................................


---------------------------------------------------------------------------
TEXT DEFINITIONS
---------------------------------------------------------------------------
Do not change the order of existing Text definitions; always add new
definitions to the end of the list. This is because Games access strings
using the index numbers of the strings, and the indices are assigned based
on the order of the Text definitions.
...........................................................................

Text
{
    ID = "";
        # Identifier of the text string.

    Text = "";
        # The string itself. Backslash (\) is used as an escape
        # character: \n = newline. Quotes (") must be escaped or the
        # parser will think the string ends ("Say \"Hello!\""). The
        # string can be divided onto multiple lines, in which case the
        # parser will skip to the first non-space character of the
        # next line when it encounters an end of line. For example
        # the following two strings are identical:
        #
        # "This is a long
        #    string?"
        #
        # "This is a longstring?"
        #
        # The escape sequence \_ translates to a normal space
        # character, so these two strings are also identical:
        #
        # "This is another long
        #   \_string."
        #
        # "This is another long string."
        #
}

...........................................................................


---------------------------------------------------------------------------
VALUE DEFINITIONS
---------------------------------------------------------------------------
The engine itself doesn't use the values for anything. You can think of the
Values definition as a registry of nested string pairs (a bit like Windows'
registry). Internally the hierarchy levels are separated with the |
(vertical line) character, so you can't use it in the key names.
...........................................................................

Values
{
    Key1 = "Example";
    My block {
        Nested key = "This is a string";
        Other key = "Hello";
    };

    # The definitions above would create the following entries:
    #
    # Key1                          Example
    # My block|Nested key           This is a string
    # My block|Other key            Hello
}

...........................................................................


---------------------------------------------------------------------------
MODEL DEFINITIONS
---------------------------------------------------------------------------
A 'Model' can be thought of as a collection of one to four MD2 models. Each
MD2 file assigned to a Model is called a submodel. Thus a Model can have up
to four submodels. In the Model definition the submodels are defined
sequentially starting from zero. The engine handles the submodels
separately, which makes it possible to interpolate the animation of each
submodel independently of the other submodels.

An example of the structure of a Model definition is given below:

Model {
    Md2 { };    # 1st submodel (submodel 0).
    Md2 { };    # 2nd submodel (submodel 1).
    Md2 { };    # 3rd submodel (submodel 2).
    Md2 { };    # 4th submodel (submodel 3).
}

One Md2 block is required, the rest should be omitted if the Model has only
one MD2 file. You can set flags in both the main Model definition and the
submodel Md2 definitions.

* Flags defined in the main definition affect all the submodels, for
  example:

  Model {
    Flags = "df_shadow1";
  }

  This means the flag will affect all the submodels of the model.

* If the Flags key is placed in a Model:Md2 definition, for example:

  Model {
    Md2 { Flags = "df_shadow1"; };
  }

  it only affects the single submodel. NOTE: a XOR operation is done so
  that using Model:Md2:Flags will reverse any flags set in Model\Flags.
  This way Model:Md2:Flags can be used to either turn off or on single
  flags that affect the whole model (depending on whether the flag is set
  in Model:Flags or not). For instance:

  Model {
    Flags = "df_shadow1";
    Md2 { Flags = "df_shadow1"; };      # Not shadowed at all.
    Md2 { Flags = "df_fullbright"; };   # Shadowed and fullbright.
    Md2 { };                            # Just shadowed.
  }

Inter and Interpolate can be used together. You can for example assign two
model frames to span across three states:

:    (Frame 1)    :    (Frame 2)    :
:                 :                 :
+-----------+-----------+-----------+ Time-->
| (State 1) | (State 2) | (State 3) |
|0         1|0   0.5   1|0         1| Inter (0..1)
D1----------D2----D3----D4----------+
:           :     :     :
:           :     :     4th defn: S3, Inter=0, Interpolate {0.333 1}
:           :     :
:           :     3rd defn: S2, Inter=0.5, Interpolate {-0.333 0.333}
:           :
:           2nd defn: S2, Inter=0, Interpolate {0.666 1.333}
:
1st definition: S1, Inter=0, Interpolate {0 0.666}

Note the 2nd definition's Interpolate end marker (1.333) and 3rd
definition's Interpolate start marker (-0.333). This is needed because the
2nd definition only extends from Inter=0 to Inter=0.5, but we want that at
Inter=0.5 the interpolation visually reaches its end (frame 1 ends and
frame 2 begins): point 0.5 in the range {0.666 1.333} is one. The 3rd
definition's case is similar, but this time the definition begins really
from Inter=0.5 and visually from the beginning (i.e. zero). When 0.5 is
scaled to the range {-0.333 0.333} we get the zero we wanted.
...........................................................................

<Copy> Model
{
    # If "Copy" is found, all the data of the previous definition is
    # copied to this one as defaults. For the first definition in a
    # file "Copy" has no effect.

    State = "";
        # The State this model will be used with.

    Off = 0;
        # Offset to state index. Use carefully! If State indices
        # change you'll be in a lot of trouble.

    Group = "";
        # One or more group IDs (mg_*). Optional.

    Selector = 0;
        # A custom value which can be used by the Game for various
        # purposes, like alternative models for some objects.

    Inter = 0.0;
        # Possible values: 0-1. Determines the point during the
        # interpolation between states when this definition becomes
        # valid. Can be used to assign several different model frames
        # to a single State.

        # NOTE: When defining models that use Inter, the definitions
        #       must be given in an ascending order; the definition
        #       with the lowest Inter comes first.

    Interpolate { 0.0 1.0 };
        # Range of interpolation. Specifies the range of the visual
        # interpolation of the model during the State. Can be used to
        # extend the interpolation of one model frame onto multiple
        # States (by defining a sub-0..1 range). Always define full
        # ranges that begin from zero and end to one.

    Flags = "";
        # Flags for the whole model, including all the submodels.
        #
        # df_fullbright: The model is rendered with the maximum light
        #       level (corresponds sector light level 255) regardless
        #       of the sector it's currently in.
        #
        # df_shadow1: The model is rendered with 33% (?) translucency.
        #       When using this flag the value of the "Transparent"
        #       key is ignored.
        #
        # df_shadow2: The model is rendered with 66% (?) translucency.
        #       When using this flag the value of the "Transparent"
        #       key is ignored.
        #
        # df_brightshadow
        # df_brightshadow2
        # df_darkshadow
        # df_movpitch
        # df_movyaw
        # df_spin
        # df_skintrans
        # df_autoscale
        #
        # df_nointerpol: Disable model vertex interpolation.
        #
        # df_alignyaw
        # df_alignpitch
        # df_idskin
        #
        # df_noz: The model is rendered with Z-buffer writes disabled.
        #
        # df_nomaxz: Model is used at all distances regardless of the 
        #        model visibility settings.
        #
        # df_selskin
        #
        # df_ptoffsub1: The center of submodel #1 is the spawn origin
        #        for particle generators.
        #
        # df_noptc
        # df_specular
        # df_litshiny
        #
        # df_idframe: An offset derived from the ID number of the object 
        #        is added to the current frame index of the object. Frame 
        #        range must also be set.
        #
        # df_idangle: The model gets a unique yaw angle offset calculated
        #        from the ID number of the object.
        #

    Skin tics = 0;
        # Skin cycle: this many tics for each skin.

    Scale = 1.0;
        # Scaling factor for the whole model (all submodels affected).
        # Uniformly sets *all* components of "Scale XYZ" to the specified
        # scaling factor.

    Scale XYZ { 1.0 1.0 1.0 };
        # Scaling factors for the whole model (all submodels affected).

    Resize = 0;
        # Automatic resizing to the given height. The whole model will
        # be scaled (only along the Y axis).

    Offset = 0.0;
        # Offset to model Y coordinate, applied when rendering.
        # Affects all submodels. Modifies the Y component of "Offset
        # XYZ".

    Offset XYZ { 0.0 0.0 0.0 };
        # Offset to model X, Y and Z coordinates, applied when
        # rendering. Affects all submodels.

    Sprite = "";
    Sprite frame = 0;
        # For autoscaling: specifies the sprite and frame to scale
        # things by. If not given, autoscaling is done based on the
        # sprite and frame associated with the State of this model.

    Shadow radius = 0;
        # With the default value of zero the shadow radius is 
        # automatically calculated.

    Md2 # Or Sub
    {
        # There can be four Md2 blocks in a Model definition.
        # Each block defines a submodel. You can use the keyword "Sub"
        # instead of Md2 to begin the block.

        File = "";
            # MD2 file, e.g. "Monst\Trooper.md2". The given file name
            # is searched from all the directories specified in the
            # model search path. The skin of the model should reside
            # in the same directory with the model (not required,
            # though: it's enough that the skin is on the model path
            # as well).

        Frame = "";
            # Name of the MD2 frame to use.
            
        Frame range = 0;
            # Used with the df_idframe flag. Defines how many consecutive
            # frames make up the range for the frame index offset, which
            # is calculated from the object's ID.

        Flags = "";
            # Flags (df_*) that affect this submodel only. A XOR
            # operation is done with the flags that affect the whole
            # model.

        Skin = 0;
            # The index number of the skin to use.

        Skin range = 0;
            # Size of the skin cycling range. The first skin in the
            # range is the one specified by Skin, and the last one is
            # (Skin) + (Skin range) - 1.

        Offset XYZ { 0.0 0.0 0.0 };
            # Offset to submodel X, Y and Z coordinates, within the
            # model.

        Transparent = 0.0;
            # Translucency of the submodel: 0=opaque, 1=transparent.
            # The level of translucency defined here is not used with
            # df_shadow1/2 or dr_brightshadow.

        Shiny skin = "";

        Shiny = 0.0;

        Shiny color { 1.0 1.0 1.0 };

        Selskin mask = 0;
            # df_selskin chooses the skin to use by looking at the
            # high byte of the selector integer. The selskin mask
            # specifies which bits of the selector special byte should
            # be considered for df_selskin.

        Selskin shift = 0;
            # After doing an AND operation with the selskin mask, the
            # resulting value is shifted to the right this many bits.
            # Negative values shift to the left.

        Selskins { 0 0 0 0 0 0 0 0 };
            # At most 8 skin numbers for df_selskin. After the special
            # byte is AND'd with the selskin mask and shifted, the
            # result is an index to this list. If the df_selskin flag
            # is set for the model, the skins in this list are used.

        Parm = 0.0;
            # Custom parameter.
    };
}

...........................................................................

Shortcuts:

* Use "Copy Model" (or "*Model") whenever possible.

* Use hyphens (-) to indicate that the previous value of the same Key
  should be used (if "Copy" was not used).

* Use ModelPath to add new model search paths. This makes it unnecessary to
  include the path in Model:Md2:File (or skin file names).


