DECOHack Help

Have you ever wanted to create some kind of insane mod for Vanilla Doom (and other classic Dooms) but wished that there was a better programmatic way to write weapon, ammo, sound, string, par time, and thing definitions with a DECORATE-like language? Introducing DECOHack, the thing that does exactly that!

DECOHack takes a file (or series of files) written in a DECORATE-ish language and turns it into a DEH/BEX file that can be loaded into your favorite source port, or patched into your favorite executable via DeHackEd! Supports all patch schemes up to DSDHACKED.

decohack code.dh --output dehacked.deh

Hate backpacks? Turn them into BFGs!

#include <doom19>
#include <friendly>

// copy BFG pickup into backpack
thing MTF_BACKPACK : thing MTF_BFG
{
	//keep ednum, though
	ednum 8
}

Make an Imp with a worse attack!

#include <doom19>
#include <friendly>

thing MTF_IMP free states
thing MTF_IMP "Worse Imp"
{
	health 200
	speed 12
	
	clear states
	States
	{
		Spawn:
			TROO AB 10 A_Look
			Loop
		See:
			TROO AABBCCDD 3 A_Chase
			Loop
		Melee:
		Missile:
			TROO EF 8 A_FaceTarget
			TROO G 6 A_BruisAttack
			Goto See
		Pain:
			TROO H 2
			TROO H 2 A_Pain
			Goto See
		Death:
			TROO I 8
			TROO J 8 A_Scream
			TROO K 6
			TROO L 6 A_Fall
			TROO M -1
			Stop
		XDeath:
			TROO N 5
			TROO O 5 A_XScream
			TROO P 5
			TROO Q 5 A_Fall
			TROO RST 5
			TROO U -1
			Stop
		Raise:
			TROO ML 8
			TROO KJI 6
			Goto See
	}
}

The sky's the limit (within reason, as it is still limited to Doom engine quirks and limitations)!

If you're worried about how many states you have left (in total or action-pointer allocated), you can run DECOHack with the `--budget` switch. Full help available via the `--help-full` switch. You can do a lot! It's all documented, even the worst of Doom's hardcodings!

Full Command and Utility Help

DECOHack v0.35.0 by Matt Tropiano (using DoomStruct v2.17.0)
Addtional feature support by Xaser Acheron.
With special thanks to Simon "fraggle" Howard (DEH9000)
and Dennis "exl" Meuwissen (WhackEd).
Usage: decohack [--help | -h | --version]
                --dump-constants
                --dump-resource [path]
                [filename] [switches]

    --help                   Prints help and exits.
    -h

    --help-full              Prints full help (not just usage) and exits.

    --version                Prints version, and exits.

    --changelog              Prints the changelog, and exits.

    --gui                    Starts the GUI version of this program.

    --dump-constants         Dumps the list of available defined constants
                             to STDOUT.

    --dump-resource [path]   Dumps an internal resource (starting with
                             "decohack/" ) to STDOUT.

    --dump-pointers          Dumps the list of Action Pointers and their
                             parameter types to STDOUT.

    --dump-pointers-html     Dumps the list of Action Pointers and their
                             parameter types to STDOUT in HTML form.

[filenames]:
    <filename> ...           The input filenames. One or more can be added,
                             parsed in the order specified.

    --                       Source input is from Standard In, not a file.

[switches]:
    --output [file]          Outputs the resultant patch to [file].
    -o [file]                If [file] is a WAD file, the output patch is added
                             or replaced in the WAD file as "DEHACKED".

    --charset [name]         Sets the input charset to [name]. The default
    -c [name]                charset is windows-1252 (system default).

    --source-output [file]   Outputs the combined source to a single file.
    -s [file]                If [file] is a WAD file, the source is added
                             or replaced in the WAD file as "DECOHACK".

    --output-charset [name]  Sets the output charset to [name]. The default
    -oc [name]               charset is ASCII, and there are not many reasons
                             to change.

    --budget                 Prints the state budget after compilation.
    -b

    --dry-run                Does no output - only attempts to compile and
                             return errors and/or warnings. Overrides all
                             output switches.

==============================================================================
============                       DECOHack                       ============
==============================================================================

DECOHack is a utility that reads a DECORATE-like syntax and outputs a DEH or 
BEX patch. You should probably read up on the ZDoom DECORATE format before 
you proceed, as some pieces are similar, and some are not.

 /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\

      IMPORTANT: It is important to note that DECOHack is CASCADING. 
      A definition of any kind will alter or replace the original 
      definition, and anything unspecified in a definition will 
      remain UNCHANGED.

 /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\

==============================================================================
===== Some Language Specs
==============================================================================

<BOOLEAN>    : true
               false

<IDENTIFIER> : Alphanumeric-plus-underscores token (starting with a letter).

<STRING>     : Any single- or double-quoted set of characters, or a raw string 
               bounded in backticks.

<INTEGER>    : Any positive integer, or hex integer (e.g. 0x01234abcd). 

<NUMBER>     : <INTEGER>
               - <INTEGER>

<FIXED>      : Any number with a decimal point in it (converted to a 
               fixed-point number). 

<NUMERIC>    : <FIXED>
               <INTEGER>
               - <FIXED>
               - <NUMBER>

==============================================================================
===== Comments
==============================================================================

You can put unparsed comments throughout your code using "//" for single-line
comments, or "/* */" for multi-line comments, like so:

    // This is a comment.
    
    /*
    This is a comment 
    on multiple lines.
    */
    
    /* Multi-line comments are
              pretty
        free          form */


You'll see them in a bunch of places in this documentation.


==============================================================================
===== Format (MUST BE SET FIRST!)
==============================================================================

To set the output format (and available features):

    using ( doom19 | udoom19 | doomunity | boom | 
            mbf | extended | mbf21 | dsdhacked )


Examples:

    using doom19
    using boom


==============================================================================
===== Strings
==============================================================================

Reassigns a set of strings. Any strings replaced here can carry through to 
sprite names and sound names!

Doom 1.9:

    strings
    {
        <INTEGER> <STRING>
        ...
    }


Boom and higher:

    strings
    {
        <IDENTIFIER> <STRING>
        ...
    }


The Identifier in the Boom definition is the string mnemonic from the Boom 
DeHackEd specs. 


==============================================================================
===== Ammo
==============================================================================

Changes an ammo entry. `ammo` plus an index, and an optional string for the 
new name. 

    ammo ( 0 | 1 | 2 | 3 ) <STRING>
    {
        max <INTEGER>
        pickup <INTEGER>
    }


Examples:

    ammo 0 "Splinters"
    {
        max 300
        pickup 20
    }
    
    ammo 2
    {
        max 5000
        pickup 100
    }


==============================================================================
===== Sound
==============================================================================

Changes a sound entry. `sound` plus the sound name. The sound name must 
match a sound string in the string table (should not start with DS or DP).

    sound <STRING>
    {
        priority <INTEGER>
        singular <BOOLEAN>
    }


Examples:

    sound "barexp"
    {
        priority 120
        singular false
    }


This pays attention to the string table's current state - the sound name must 
be changed (if you want to change it) before it is referred to by name, here.
Note that you can't change sound names in Boom or higher.


==============================================================================
===== States
==============================================================================

Individual states can be manipulated and/or changed, but be careful - 
individual state manipulation should only be reserved for very few kinds of 
changes.

    state <INTEGER> 
    { 
        [ <SpriteName> <Frame> <NUMBER> [Bright] <StateFlags> [<Offset>] [<ActionPointer>] ]
        ( 
            goto <INTEGER> 
            | goto <IDENTIFIER>
            | goto weapon <INTEGER> <WeaponStateLabel>
            | goto thing <INTEGER> <ThingStateLabel>
            | wait 
            | stop 
        )
    }


In this case, "stop" is an alias for "goto 0", and "wait" is an alias for 
"goto <last defined state>". <SpriteName> must match a sprite name in the 
string table at the time this is declared. <Frame> must be a single valid 
character in a sprite frame. <NUMBER> is the duration in tics. [Bright] is an
optional keyword indicating that the state graphic is always painted 
fullbright.

<StateFlags>, available in MBF21 or later, are additional flags placed on
individual states. State flags are only completely overwritten if at least one
is specified in the state declaration. The only state flags available in this 
patch type are:

    Fast      This frame's duration is halved in Nightmare.

    NotFast   This frame's duration is NOT halved in Nightmare. This is
              only useful for states that already had it, but just want
              to clear flags by specifying at least one flag.


Action pointer mnemonics must start with "A_". Some action pointers, 
especially in MBF and later formats, can be optionally parameterized up to two
parameters (or greater, if MBF21):

    A_Die
    A_Die()
    A_Turn(90)
    A_RandomJump(344, 128)


Parameter values can also resolve to values via thing or weapon label names, 
sound indices, and references to thing or weapon state labels (like how goto 
is used).

    A_RandomJump(missile2, 255)         // Available state label on same actor
    A_RandomJump(thing 23 pain, 128)    // Thing state label
    A_RandomJump(weapon 5 fire2, 128)   // Weapon state label
    A_PlaySound("FRE001", 0)            // Sound name
    A_PlaySound(pistol, 0)              // Sound name


Some parameter values can be set with fixed-point numbers, but not every 
function requires them or understands them:

    A_Mushroom(-45.0, 16.0)


Depending on the expected parameter type, DECOHack will automatically convert
those parameters to fixed-point. The following is equivalent to the above:

    A_Mushroom(-45, 16)


Parameter values can also be a series of flags that get or'ed together. This
is useful for some functions that manipulate flags. A set of supported flags 
can be combined via the PIPE operator (or pluses):

    A_AddFlags(SOLID | DROPPED, 0)
    A_AddFlags(SOLID + DROPPED, 0)


DECOHack calculates a single value from these expressions. The only checking 
done is if those flags are valid for the patch level (i.e. MBF, EXTENDED, or 
MBF21).

NOTE: Some flags may share names with valid labels. To force DECOHack to 
interpret a parameter as a label, wrap it in quotes (it may be a good idea to
do this anyway, for readability).

    A_RandomJump("missile", 64)


Also, similarly, to force DECOHack to interpret an expression as a flag 
expression, prefix it with the "flags" keyword:

    A_AddFlags(flags SOLID | DROPPED, 0)


Weapon states have a special characteristic that went unused for the most part
in Doom, but is still modifiable in DECOHack. You can set the offset of the
weapon graphic on the frame (but note that it will only apply it if the first
argument is nonzero).

    Offset(1, 32)


Action pointers understand what is expected in each parameter - you can just
refer to thing aliases, labels, and sounds or what-have-you as-is and it
will attempt to figure it out:

    A_Spawn(Demon, 0.0)                           // Thing alias
    A_Scratch(10, punch)                          // Sound name
    A_RandomJump(pain2, 128)                      // State label
    A_HealChase(heal, slop)                       // State label, sound name
    A_WeaponSound(shotg3, 1)                      // Sound name
    A_WeaponProjectile(CacodemonBall, 0, 0, 0, 0) // Thing alias


 /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\

      IMPORTANT: Some MBF pointers use the miscellaneous offset fields
      as function parameters, so attempting to use Offset on those
      weapon states that use them will cause an error! You can still 
      use Offset with Doom/Ultimate Doom 1.9 and MBF21 pointers - those 
      do not use those fields at all.
      
 /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\


You can also use a shorthand for doing multiple actions on "one" state by 
putting a set of multiple code pointers in braces:

    // a very mean mancubus
    MANC H 10 Bright {
        A_FatAttack1
        A_FatAttack2
        A_FatAttack3
    }


Note that what is generated is NOT one state - states cannot have more than 
one action pointer. Rather, the result is a bunch of states:

    MANC H 0 Bright A_FatAttack1
    MANC H 0 Bright A_FatAttack2
    MANC H 10 Bright A_FatAttack3


The duration on every state is 0 except for the last one, which simulates
several actions on "one" state. This works for action pointers that also
have parameters. The following: 

    TNT1 A 0 A_SpawnObject(DoomImpBall, 0.0, 0.0, 0.0, 16.0, 4.0, 0.0, 0.0)
    TNT1 A 0 A_SpawnObject(DoomImpBall, 0.0, 0.0, 0.0, 16.0, -4.0, 0.0, 0.0)
    TNT1 A 0 A_SpawnObject(DoomImpBall, 0.0, 0.0, 0.0, 16.0, 0.0, 4.0, 0.0)
    TNT1 A 4 A_SpawnObject(DoomImpBall, 0.0, 0.0, 0.0, 16.0, 0.0, -4.0, 0.0)


...could be collapsed to:

    TNT1 A 4 { 
        A_SpawnObject(DoomImpBall, 0.0, 0.0, 0.0, 16.0, 4.0, 0.0, 0.0)
        A_SpawnObject(DoomImpBall, 0.0, 0.0, 0.0, 16.0, -4.0, 0.0, 0.0)
        A_SpawnObject(DoomImpBall, 0.0, 0.0, 0.0, 16.0, 0.0, 4.0, 0.0)
        A_SpawnObject(DoomImpBall, 0.0, 0.0, 0.0, 16.0, 0.0, -4.0, 0.0)
    }


You could even couple this with some #define preprocessor directives if you
end up doing the same thing for multiple things:

    #define A_SuperFatAttack { A_FatAttack1 A_FatAttack2 A_FatAttack3 }
    
    MANC H 10 Bright A_SuperFatAttack


...which the preprocessor will turn into:

    MANC H 10 Bright { A_FatAttack1 A_FatAttack2 A_FatAttack3 }


...and compiles down to:

    MANC H 0 Bright A_FatAttack1
    MANC H 0 Bright A_FatAttack2
    MANC H 10 Bright A_FatAttack3


Individual state manipulation can have partial changes to its properties
instead of using a full state definition line:

    state <INTEGER>
    {
        spritename <SpriteName> 
        frame <Frame> 
        duration <NUMBER> 
        [Bright]
        [NotBright]
        [Fast]      // MBF21 Only
        [NotFast]   // MBF21 Only 
        [<OffsetClause>]
        pointer [ <ActionPointer> | null ]
        nextstate <StateIndex>
    }


More examples:

    state 11
    {
        PISG A 1 A_Lower
        wait
    }

    state 13
    {
        PISG A 4 Offset(1, 32)
        goto 16
    }

    state 16
    {
        PISG C 4
        goto 17
    }

    state 16
    {
        duration 1
    }

    state 17
    {
        PISF A 7 Bright A_Light1
        goto 1
    }

    state 173
    {
        PLAY W -1
        stop
    }

    state 575 // change just next state
    {
        goto 577
    }
    
    state 911
    {
        CAND A -1 Bright
        stop
    }

    state 911
    {
        notbright
        pointer null
    }


For replacing states in bulk, you will have to "free" a bunch of states for
replacement.

    state free <INTEGER>


To free an explicit range (inclusive):

    state free <INTEGER> to <INTEGER>


To free from a starting state index, following next state indices until a 
free or protected state is reached:

    state free from <INTEGER>


Examples:

    state free 100
    state free 100 to 200
    state free from 100


 /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\

      IMPORTANT: "Freeing" a state does NOT ALTER IT, it just flags 
      that state as "available" for the state-filling functions in 
      this utility.

 /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\


Then, you can fill a sequence of states starting from a specific state, and
free states will be auto-filled by availability, connected together in 
sequence. Be careful: it may fail with an error if you run out of available
states (especially action pointer states in Doom 1.9).

    state fill <INTEGER> 
    { 
        <SpriteName> <Frames> <NUMBER> [Bright] [<ActionPointer>|<Offset>]
        ...
        (
            goto <INTEGER> 
            | goto <IDENTIFIER>
            | goto weapon <INTEGER> <WeaponStateLabel>
            | goto thing <INTEGER> <ThingStateLabel>
            | wait 
            | stop 
            | loop 
        )
    }


<Frames> in this situation can be many valid characters in a sprite frame.


Examples:
    
    state fill 714
    {
        PAIN H 8 Bright
        PAIN I 8 Bright A_Scream
        PAIN JK 8 Bright
        PAIN L 8 Bright A_PainDie
        PAIN M 8 Bright
        stop
    }


Each state altered directly (via "state X") or filled in this manner are no 
longer "free."

You can protect a state from being freed (or an inclusive range of them) by 
writing the following:

    state protect <INTEGER>
    state protect <INTEGER> to <INTEGER>


You can also use a state clause in place of an integer for the first clause:

    state protect thing 11 spawn


Be careful though - it will protect the state at that resolved index, not 
anything regarding the label specifically.


It will not be flagged as "free" if in a range of free states, it won't be 
treated as "free" in state filling functions, and attempting to alter the 
state directly will throw an error. By default, state 0 and 1 are flagged as 
protected. You can turn off the protection on states by doing the following:

    state unprotect <INTEGER>
    state unprotect <INTEGER> to <INTEGER>


 /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\

      IMPORTANT: DECOHack is intentionally not very smart about 
      figuring out user intent, especially around states with hardcoded 
      purpose, in order to keep patch crafting as flexible as possible. 
      For example, one such state, State 266 (S_VILE_HEAL1), is the 
      state that the action pointer "A_VileChase" can make an actor
      jump to when it resurrects a dead monster, despite the fact
      that it is not referenced ANYWHERE on a thing definition's
      state pointers!
      
      Please view "DeHackEd Hardcodings.txt" in the docs folder for
      more info!
 
 /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\


==============================================================================
===== Weapon
==============================================================================

Weapons are a combination of state filling and attribute declaration. All
definitions are cumulative on the weapon slot (separate definitions can alter 
the same slot in different ways).

Ready, Select, Deselect, Fire, and Flash state labels set the weapon state 
indices. Other labels are used for arbitrary jump points. "LightDone" is a 
built-in alias for state 1.

Unlike ZDoom DECORATE, the "Spawn" state is not used, as that is used by an 
associated Thing for pickups.

    weapon <INTEGER> [ : weapon <INTEGER> ] [ <STRING> ] 
    {
        ammotype ( 0 | 1 | 2 | 3 | 5 )
        
        //MBF21 fields
        ammopershot <INTEGER>
        flags mbf21 <INTEGER-EXPRESSION>
        
        clear properties // If present, clear all properties.

        clear flags // If present, clear all flags (both sets, if available)

        // MBF21 Flags (MBF21 feature set only)
        + mbf21 <INTEGER>           // set flag(s)
        - mbf21 <INTEGER>           // unset flag(s)
        + <MBF21WeaponFlagName>     // set flag
        - <MBF21WeaponFlagName>     // unset flag
        
        // specific state assignment.
        state <WeaponStateName> <INTEGER>
        
        // specific state assignment using another thing's states.
        state <WeaponStateName> thing <INTEGER or ThingAlias> <ThingStateLabel>
        
        // specific state assignment using another weapon's states.
        state <WeaponStateName> weapon <INTEGER or WeaponAlias> <WeaponStateLabel>
        
        // if present, clear all state indices (not freed!).
        clear states 

        // clears a specific label (not freed!).
        clear state <WeaponStateLabel>
        
        states
        {
            ready:
                <StateInfo>
                ...
            deselect:
                <StateInfo>
                ...
            select:
                <StateInfo>
                ...
            fire:
                <StateInfo>
                ...
            flash:
                <StateInfo>
                ...
        }
    }


Example:

    weapon 2 "Shotgun"
    {
        ammotype 1
        clear states
        states
        {
            ready:
                SHTG A 1 A_WeaponReady
                loop
            deselect:
                SHTG A 1 A_Lower
                loop
            select:
                SHTG A 1 A_Raise
                loop
            fire:
                SHTG A 3
                SHTG A 7 A_FireShotgun
                SHTG BC 5
                SHTG D 4
                SHTG CB 5
                SHTG A 3
                SHTG A 7 A_ReFire
                goto ready
            flash:
                SHTF A 4 Bright A_Light1
                SHTF B 3 Bright A_Light2
                goto lightdone
        }
    }


 /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\

      IMPORTANT: Using "goto" or other "jump" actions to jump to 
      labels/state pointers that you have not set or re-declared 
      within a "states" block will jump to whatever state is already 
      declared for that label!
 
 /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\

To flag all states as "free" that are connected to a weapon, type the 
following:

    weapon <INTEGER> free states
    weapon <INTEGER> free <WeaponStateName>


And the same result will happen if you freed from each defined weapon frame 
individually. Best used before redefining a weapon. NOTE: "Freeing" is NOT
the same as clearing the state definitions!

You can copy from another weapon slot by adding the [ : weapon <INTEGER> ] 
clause:

    weapon 3 : weapon 4 "New Weapon Name"
    {
        ...
    }


 /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\

      IMPORTANT: DECOHack does NOT have any concept of "inheritance"
      as DECORATE does. The copy via the ":" is a straight-up 
      definition copy, and does not have a concept of "super" or
      "parent" objects of any kind! 
 
 /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\


All weapon characteristics and state labels get copied.

You can also swap two weapon slots:

    weapon 3 swap with 4


Multiple weapons can be edited as though each weapon were changed 
individually via an "each" clause like so:

    each weapon from <INTEGER> to <INTEGER>
    {
        // ... weapon properties ...
    }

    each weapon in ( <INTEGER or WeaponAlias> , ... )
    {
        // ... weapon properties ...
    }


For example, you can make all of the weapons have infinite ammo:

    each weapon from 0 to 8
    {
        ammotype 5
    }


Or maybe just the pistol and chaingun:

    each weapon in (1, 3)
    {
        ammotype 5
    }


If states are filled across the set of weapons, any special frame indices
will set to the EXACT same value across all of the specified weapons (i.e., 
the same Select state, the same Fire state, etc.). 


------------------------------------------------------------------------------
Weapon Aliases
------------------------------------------------------------------------------

You can specify identifier aliases for weapon slots by using the following:

    alias weapon Shotgun 2


...so the next time you refer to it, you can write:

    weapon Shotgun
    {
        // ... code
    }


The alias works in every place you can use a weapon reference:  

    weapon Shotgun free states

    weapon 4 : weapon Shotgun "Shotgun Copy"
    {
        // ... weapon body
    }


Weapon alias identifiers are case-insensitive. There are a few internal 
"#includes" that will add these common ZDoom weapon names by default. 


==============================================================================
===== Thing
==============================================================================

Things are a combination of state filling and attribute declaration. All
definitions are cumulative on the thing slot (separate definitions can alter 
the same slot in different ways).

Spawn, See, Melee, Missile, Pain, Death, XDeath, and Raise state labels set 
the thing state indices. Other labels are used for arbitrary jump points.

    thing <INTEGER> [ : thing <INTEGER> ] [ <STRING> ] 
    {
        clear properties // If present, clear all properties.
        
        ednum <NUMBER>
        
        health <NUMBER>
        speed <NUMBER>
        radius <INTEGER>
        height <INTEGER>
        damage <NUMBER>
        reactiontime <INTEGER>
        painchance <INTEGER>
        mass <INTEGER>

        flags <INTEGER-EXPRESSION>

        flags mbf21 <INTEGER-EXPRESSION> // MBF21 Only

        clear flags // If present, clear all flags (both sets, if available)

        + <INTEGER>                  // set flag(s)
        - <INTEGER>                  // unset flag(s)
        + <ThingFlagName>            // set flag
        - <ThingFlagName>            // unset flag

        // MBF21 Flags (MBF21 feature set only)
        + mbf21 <INTEGER>            // set flag(s)
        - mbf21 <INTEGER>            // unset flag(s)
        + <MBF21ThingFlagName>       // set MBF21 flag
        - <MBF21ThingFlagName>       // unset MBF21 flag

        clear sounds // if present, clear all sounds.
            
        seesound <STRING>
        attacksound <STRING>
        painsound <STRING>
        deathsound <STRING>
        activesound <STRING>

        // Extended Properties (Extended/DEHEXTRA feature set and later)
        dropitem <INTEGER or ThingAlias>
        
        // MBF21 Properties (MBF21 feature set and later)
        fastspeed <INTEGER>
        meleerange <INTEGER>
        infightinggroup <INTEGER>
        projectilegroup <INTEGER>
        splashgroup <INTEGER>
        ripsound <STRING>

        // specific state assignment.
        state <ThingStateName> <INTEGER>
        
        // specific state assignment using another thing's states.
        state <ThingStateName> thing <INTEGER or ThingAlias> <ThingStateLabel>
        
        // specific state assignment using another weapon's states.
        state <ThingStateName> weapon <INTEGER or WeaponAlias> <WeaponStateLabel>
        
        // if present, clear all state indices (not freed!).
        clear states

        // clears a specific label (not freed!).
        clear state <ThingStateLabel>
        
        states
        {
            spawn:
                <StateInfo>
                ...
            see:
                <StateInfo>
                ...
            missile:
                <StateInfo>
                ...
            pain:
                <StateInfo>
                ...
            death:
                <StateInfo>
                ...
            xdeath:
                <StateInfo>
                ...
            raise:
                <StateInfo>
                ...
        }
    }


Example:

    thing 11 "Chaingun Sargeant"
    {
        EdNum 65
        
        Health 70
        Speed 8
        Radius 20
        Height 56
        Damage 0
        ReactionTime 8
        PainChance 170
        Mass 100
    
        clear flags
        +SOLID
        +SHOOTABLE
        +COUNTKILL
    
        SeeSound "posit2"
        AttackSound ""
        PainSound "popain"
        DeathSound "podth2"
        ActiveSound "posact"
        
        states
        {
            Spawn:
                CPOS AB 10 A_Look
                Loop
            See:
                CPOS AABBCCDD 3 A_Chase
                Loop
            Missile:
                CPOS E 10 A_FaceTarget
            ReFire:
                CPOS FE 4 Bright A_CPosAttack
                CPOS F 1 A_CPosRefire
                Goto ReFire
            Pain:
                CPOS G 3
                CPOS G 3 A_Pain
                Goto See
            Death:
                CPOS H 5
                CPOS I 5 A_Scream
                CPOS J 5 A_Fall
                CPOS KLM 5
                CPOS N -1
                Stop
            XDeath:
                CPOS O 5 
                CPOS P 5 A_XScream
                CPOS Q 5 A_Fall
                CPOS RS 5
                CPOS T -1
                Stop
            Raise:
                CPOS N 5
                CPOS MLKJIH 5
                Goto See
        }
    }


 /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\

      IMPORTANT: Using "goto" or other "jump" actions to jump to 
      labels/state pointers that you have not set or re-declared 
      within a "states" block will jump to whatever state is already 
      declared for that label!
 
 /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\


To flag all states as "free" that are connected to a thing, type the 
following:

    thing <INTEGER> free states
    thing <INTEGER> free <ThingStateName>


And the same result will happen if you freed from each defined thing frame 
individually. Based on the current thing definition. Best used before 
redefining a thing. NOTE: "Freeing" is NOT the same as clearing the state 
definitions!

The following editor numbers cannot be used: 1, 2, 3, 4, or 11, as they have
a special purpose: Player Starts, plus Deathmatch.

You can copy from another thing slot by adding the [ : thing <INTEGER> ] 
clause:

    thing 3 : thing 4 "New Name"
    {
        ...
    }


All thing characteristics and state labels get copied.


 /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\

      IMPORTANT: DECOHack does NOT have any concept of "inheritance"
      as DECORATE does. The copy via the ":" is a straight-up 
      definition copy, and does not have a concept of "super" or
      "parent" objects of any kind! 
 
 /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\


You can also swap two thing slots:

    thing 3 swap with 4


Multiple things can be edited as though each thing were changed individually 
via an "each" clause like so:

    each thing from <INTEGER> to <INTEGER>
    {
        // ... thing properties ...
    }

    each thing in ( <INTEGER or ThingAlias> , ... )
    {
        // ... thing properties ...
    }


For example, you can make all of the hanging bodies non-solid:

    each thing from 129 to 134
    {
        -SOLID
    }


Or maybe make some slower projectiles really fast and damaging!

    each thing in (7, 17, 32, 33, 37)
    {
        speed 25
        damage 10
    }


If states are filled across the set of things, any special frame indices
will set to the EXACT same value across all of the specified things (i.e., 
the same Spawn state, the same Missile state, etc.).


------------------------------------------------------------------------------
Thing Aliases
------------------------------------------------------------------------------

You can specify identifier aliases for thing slots by using the following:

    alias thing DoomImp 12


...so the next time you refer to it, you can write:

    thing DoomImp
    {
        // ... code
    }


The alias works in every place you can use a thing reference or slot:  

    thing DoomImp free states
    
    A_Jump(thing DoomImp death)

    thing 200 : thing DoomImp "Imp Copy"
    {
        // ... thing body
    }


Thing alias identifiers are case-insensitive. There are a few internal 
"#includes" that will add these common ZDoom thing names by default. 


------------------------------------------------------------------------------
Auto-Things
------------------------------------------------------------------------------

Things can be freed and filled automatically like states. To free a single
thing slot:

    thing free <INTEGER>


To free an explicit range (inclusive):

    thing free <INTEGER> to <INTEGER>


Examples:

    thing free 151
    thing free 151 to 250


In order to fill the next free Thing, you need to define Things using the 
"auto" keyword:  

    auto thing <IDENTIFIER> [ : thing ( <INTEGER> | <IDENTIFIER> ) ] [ <STRING> ]
    {
        // ... same thing body like always ...
    }


Note that you'll need to use an unused identifier (or alias) to represent the 
new Thing when you need to refer to its index later. The identifiers are 
case-insensitive.

Examples:

    auto thing NewImp "New Imp"
    {
        // ... code ...
    }

    auto thing BetterImp : thing NewImp "Better Imp"
    {
        // ... code ...
    }


...then in action pointer functions (and other places that use thing 
references), you can refer to them later since they are now aliased:

    A_SpawnThing(NewImp)
    A_RandomJump(thing NewImp death, 128)  // Label in a specific thing


Any place that would ordinarily use a Thing index can use an auto-thing 
identifier in place of the index.

Things that are edited directly or auto-filled this way are not "free" 
anymore, similar to how "free" states work.

You can modify auto-filled Things later (remember, definitions cascade!) by
writing a normal Thing definition body:

    thing BetterImp
    {
        // ... code ...
    }


 /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\

      IMPORTANT: DECOHack will not warn you about Thing slots with a
      special purpose being filled this way! Most of the time, auto-
      things are useful for EXTENDED and higher patch types. Be
      VERY careful if you use this feature in Vanilla or Boom!
 
 /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\


You can also influence the next "auto thing" index/slot to be used via a 
special clause:

    set next auto thing index <INTEGER>

...where <INTEGER> is a positive integer for setting the next seek index for
"auto" things. This may not write to the exact slot for the next thing, 
however - it will still seek to the next "free" slot from that provided index! 

------------------------------------------------------------------------------
Thing Editor Keys
------------------------------------------------------------------------------

https://zdoom.org/wiki/Editor_keys

DECOHack Things also support the Editor Keys that are read by map editors
like Ultimate Doom Builder or SLADE, except the supported keys are passed 
along to the resultant DEHACKED file. The following keys are detected:

//$Angled
//$NotAngled
//$Category <String>
//$Group <String>
//$Color <Integer>
//$Colour <Integer>
//$Sprite <String>
//$EditorSprite <String>


------------------------------------------------------------------------------
Flag Mnemonics
------------------------------------------------------------------------------

Instead of integers, you can use the following mnemonics for object flags:

List of valid mnemonics and their values:

Things (Doom+):

    SPECIAL =        0x00000001
    SOLID =          0x00000002
    SHOOTABLE =      0x00000004
    NOSECTOR =       0x00000008
    NOBLOCKMAP =     0x00000010
    AMBUSH =         0x00000020
    JUSTHIT =        0x00000040
    JUSTATTACKED =   0x00000080
    SPAWNCEILING =   0x00000100
    NOGRAVITY =      0x00000200
    DROPOFF =        0x00000400
    PICKUP =         0x00000800
    NOCLIP =         0x00001000
    SLIDE =          0x00002000
    FLOAT =          0x00004000
    TELEPORT =       0x00008000
    MISSILE =        0x00010000
    DROPPED =        0x00020000
    SHADOW =         0x00040000
    NOBLOOD =        0x00080000
    CORPSE =         0x00100000
    INFLOAT =        0x00200000
    COUNTKILL =      0x00400000
    COUNTITEM =      0x00800000
    SKULLFLY =       0x01000000
    NOTDMATCH =      0x02000000
    TRANSLATION =    0x04000000
    TRANSLATION1 =   0x04000000
    UNUSED1 =        0x08000000
    TRANSLATION2 =   0x08000000
    TOUCHY =         0x10000000
    UNUSED2 =        0x10000000
    BOUNCES =        0x20000000
    UNUSED3 =        0x20000000
    FRIEND =         0x40000000
    FRIENDLY =       0x40000000
    UNUSED4 =        0x40000000
    TRANSLUCENT =    0x80000000

Things (MBF21+):

    LOGRAV =         0x00000001
    SHORTMRANGE =    0x00000002
    DMGIGNORED =     0x00000004
    NORADIUSDMG =    0x00000008
    FORCERADIUSDMG = 0x00000010
    HIGHERMPROB =    0x00000020
    RANGEHALF =      0x00000040
    NOTHRESHOLD =    0x00000080
    LONGMELEE =      0x00000100
    BOSS =           0x00000200
    MAP07BOSS1 =     0x00000400
    MAP07BOSS2 =     0x00000800
    E1M8BOSS =       0x00001000
    E2M8BOSS =       0x00002000
    E3M8BOSS =       0x00004000
    E4M6BOSS =       0x00008000
    E4M8BOSS =       0x00010000
    RIP =            0x00020000
    FULLVOLSOUNDS =  0x00040000

Weapons (MBF21+):

    NOTHRUST =       0x00000001
    SILENT =         0x00000002
    NOAUTOFIRE =     0x00000004
    FLEEMELEE =      0x00000008
    AUTOSWITCHFROM = 0x00000010
    NOAUTOSWITCHTO = 0x00000020


Monsters tend to have 0x00400006 set (SOLID, SHOOTABLE, COUNTKILL).

Projectiles tend to have 0x00010610 set (MISSILE, NOGRAVITY, DROPOFF, 
NOBLOCKMAP).

Example:

    +SOLID
    -NOGRAVITY
    +RANGEHALF


==============================================================================
===== Custom Action Pointers
==============================================================================

There may be some patches that accept bespoke actions or action functions that
are not known to DECOHack, or actions that port authors include that may not
be "standard". For those, you can specify custom pointers for use on Thing
or Weapon states:

    custom thing pointer <PatchType> A_PointerName ( <ParameterType> [ , <ParameterType> ...] )
    custom weapon pointer <PatchType> A_PointerName ( <ParameterType> [ , <ParameterType> ...] )


Where <PatchType> is:

    boom       // no parameters, allow Offset
    mbf        // two parameters max, store in Misc fields, disallow Offset if at least one parameter
    mbf21      // ten parameters max, store in Args fields, allow Offset


...which describes how many parameters the function can take and how it's
stored in the patch (misc fields, or args).

<ParameterType> is:

    bool         // 0 or 1
    byte         // -127 to 127
    ubyte        // 0 to 255
    short        // -32767 to 32767
    ushort       // 0 to 65535
    int          // -2147483648 to 2147483647
    uint         // 0 to 2147483647
    angleint     // -359 to 359
    angleuint    // 0 to 359
    anglefixed   // -359.99998 to 359.99998
    fixed        // -32768.99998 to 32767.99998
    state        // 0 to 2147483647, verify valid state index, reference, or label.
    thing        // 0 to 2147483647, verify valid thing index.
    thingmissile // 0 to 2147483647, verify valid thing index, and thing is a MISSILE.
    weapon       // 0 to 2147483647, verify valid weapon index.
    sound        // valid sound name.
    flags        // -2147483648 to 2147483647, flag expression


For example, a popular non-standard pointer, MonsterRail:

    custom thing pointer boom A_MonsterRail()


...and its counterpart, FireRailgun:

    custom weapon pointer boom A_FireRailgun()


...the Mushroom pointer from MBF:

    custom thing pointer mbf A_Mushroom(anglefixed, fixed)


...the WeaponMeleeAttack pointer from MBF21:

    custom weapon pointer mbf21 A_WeaponMeleeAttack(ushort, uint, fixed, sound, fixed)


 /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\

      IMPORTANT: This is only supported for Boom and higher, since those 
      patch formats refer to action pointers by mnemonic - defining a 
      custom pointer as "A_PointerName" will write "PointerName" to the 
      correct place in the [CODEPTR] section of the patch. Name your 
      experimental pointers accordingly!

 /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\


==============================================================================
===== Custom Properties
==============================================================================

There are some ports out there that accept additional DeHackEd properties. In
order to use those, you have to declare them ahead of time, like custom action
pointers.

    custom <Object> property <Name> <DEHLabel> <ValueType>

...where <Object> is one of: 

    thing, weapon, misc, state, sound, ammo
    
...and <Name> is the property name.

...and <DEHLabel> is the DeHackEd entry name when the DEH patch gets written.

...and <ValueType> is one of: 

    bool         // 0 or 1
    byte         // -127 to 127
    ubyte        // 0 to 255
    short        // -32767 to 32767
    ushort       // 0 to 65535
    int          // -2147483648 to 2147483647
    uint         // 0 to 2147483647
    angleint     // -359 to 359
    angleuint    // 0 to 359
    anglefixed   // -359.99998 to 359.99998
    fixed        // -32768.99998 to 32767.99998
    state        // 0 to 2147483647, verify valid state index, reference, or label.
    thing        // 0 to 2147483647, verify valid thing index.
    thingmissile // 0 to 2147483647, verify valid thing index, and thing is a MISSILE.
    weapon       // 0 to 2147483647, verify valid weapon index.
    sound        // valid sound name.
    flags        // -2147483648 to 2147483647, flag expression
    string       // any string expression, written as-is.


For example, Doom Retro's "gib health" property for Things can be defined as:

    custom thing property gibhealth "Gib health" int


==============================================================================
===== Par Times
==============================================================================

Only for certain patch formats (Boom-compatible), Par Times are declared this 
way:

    pars
    {
        <MapName> <INTEGER>           // seconds
        <MapName> <INTEGER>:<INTEGER> // minutes:seconds
    }

Where <MapName> is a map lump (map or episode-map is derived from it), and
<INTEGER> is the par time in SECONDS (or <INTEGER>:<INTEGER> is 
minutes:seconds).

Examples:

    pars
    {
        e1m1 30
        map20 150
        map20 2:30
        map45 200
    }


Note that DECOHack is not prudent enough to check for "valid" minutes and 
seconds. The formula, no matter what is entered, is always:

    (minutes * 60) + seconds

...which means that a value of 81:75 is considered perfectly valid:

    (81 * 60) + 75 = 4935 sec.


==============================================================================
===== Miscellany
==============================================================================

Miscellaneous data is in the miscellaneous block:

    misc
    {
        monstersFightOwnSpecies <BOOLEAN>
        initialBullets <INTEGER>
        initialHealth <INTEGER>
        greenArmorClass <INTEGER>
        blueArmorClass <INTEGER>
        soulsphereHealth <INTEGER>
        maxSoulsphereHealth <INTEGER>
        megasphereHealth <INTEGER>
        godModeHealth <INTEGER>
        idfaArmor <INTEGER>
        idfaArmorClass <INTEGER>
        idkfaArmor <INTEGER>
        idkfaArmorClass <INTEGER>
        bfgCellsPerShot <INTEGER>
        maxHealth <INTEGER>
        maxArmor <INTEGER>
    }


==============================================================================
===== SPECIAL: DSDHACKED Patch Behavior 
==============================================================================

DSDHACKED patches introduce a way to extend sprite names and sounds. DECOHack
will extend these automatically whenever a new sprite is referred to in state
definitions or a new sound is referred to in parameters or in sound 
definitions as though they already exist.

If any sprite name uses characters that are not available (or legal) in an 
identifier, you need to wrap the name in quotes:

    "TR-X" ABCD 5 A_Chase  
    "00BF" G 10 Bright


NOTE: These features are only enabled for patches that employ a DSDHACKED 
(or better) feature set!

You can also affect what the next available sprite or sound index is with the 
following clauses:

    set next sound index <INTEGER>
    set next sprite index <INTEGER>

...where <INTEGER> is a positive integer GREATER THAN OR EQUAL TO the current
sprite or sound index (for safety reasons). For example:

    set next sound index 1000
    set next sprite index 350


==============================================================================
===== Preprocessor
==============================================================================

DECOHack has a C-like preprocessor. The following directives influence how
a DECOHack file is parsed.

------------------
#include
------------------

The #include directive includes the contents of the specified file. The 
filename is provided as a string parameter, and can either be a relative file 
path from the file that contains the directive or an absolute path. Files can 
be included more than once - use this with caution!

    #include "scenery.dh"
    #include "maps/mapnames.dh"


You can include some internal resource files by prefixing the file path with
"classpath:" and it will attempt to read that file from the Java classpath.
 
    #include "classpath:decohack/constants/doom19.dh"
 

There are a few #include paths that are aliased in DECOHack for convenience:
 
    <doom19>    "classpath:decohack/doom19.dh"
    <udoom19>   "classpath:decohack/udoom19.dh"
    <doomunity> "classpath:decohack/doomunity.dh"
    <boom>      "classpath:decohack/boom.dh"
    <mbf>       "classpath:decohack/mbf.dh"
    <extended>  "classpath:decohack/extended.dh"
    <mbf21>     "classpath:decohack/mbf21.dh"
    <dsdhacked> "classpath:decohack/dsdhacked.dh"
    <friendly>  "classpath:decohack/constants/friendly_things.dh"

For example:

    #include <mbf21>

...is exactly the same as:

    #include "classpath:decohack/mbf21.dh"


------------------
#define
------------------

The #define directive defines a single-token macro that expands to a series of
other tokens. This is also useful for creating defines and testing if they 
were defined later. They may also expand to zero tokens. All macro tokens are 
CASE SENSITIVE!

NOTE: Unlike the C-language preprocessor, this does not create macro 
functions.

    #define GREETING_TEXT "Hello."
    #define FILE_WAS_INCLUDED


#define lines can be multi-line, if each line is ended with a backslash:

    #define CLEARED_THING { \
        clear flags \
        clear sounds \
        clear states \
        state spawn thing MTF_CANDLE spawn \
    }


------------------
#undefine
------------------

The #undefine directive removes a previously defined macro. All subsequent 
uses of that macro are treated as though they were never defined.

    #define GREETING_TEXT "Hello."
    #undefine GREETING_TEXT


------------------
#ifdef
------------------

The #ifdef directive includes the next series of lines if the following macro
was defined, until it reaches an #endif directive.

    #define DOOM_STRINGS
    #ifdef DOOM_STRINGS
    #include "strings/doom.dh"
    #endif


------------------
#ifndef
------------------

The #ifdef directive includes the next series of lines if the following macro 
was NOT defined, until it reaches an #endif directive.

    #define NO_PAR_TIMES
    #ifndef NO_PAR_TIMES
    pars 
    { 
        e1m1 0:40 
    }
    #endif
    

------------------
#else
------------------

The #else directive ends the most recently started "if" directive block and 
provides an alternate section if the first "if" is not processed.


    #define TOUGH_PAR_TIMES
    #ifdef TOUGH_PAR_TIMES
    #include "maps/tough-partimes.dh"
    #else
    #include "maps/normal-partimes.dh"
    #endif


------------------
#endif
------------------

The #endif directive ends the most recently started "if" or "else" directive 
block.


==============================================================================
===== Built-in Resources
==============================================================================

#include <doom19>
#include "classpath:decohack/doom19.dh"

    Adds ammo, state, weapon slot, thing slot, and string mnemonics for 
    Doom 1.9 EXEs, plus the "using doom19" line. Also adds ZDoom thing and
    weapon aliases.

#include <udoom19>
#include "classpath:decohack/udoom19.dh"

    Adds ammo, state, weapon slot, thing slot, and string mnemonics for 
    Ultimate Doom 1.9 EXEs, plus the "using udoom19" line. Also adds ZDoom 
    thing and weapon aliases.

#include <doomunity>
#include "classpath:decohack/doomunity.dh"

    Adds ammo, state, weapon slot, thing slot, and string mnemonics for 
    Ultimate Doom 1.9 EXEs, plus the "using doomunity" line. Also adds ZDoom 
    thing and weapon aliases, and does not limit string lengths.

#include <boom>
#include "classpath:decohack/boom.dh"

    Adds ammo, state, weapon slot, thing slot, and string mnemonics for 
    Boom-compatible ports, plus the "using boom" line. Also adds ZDoom 
    thing and weapon aliases.

#include <mbf>
#include "classpath:decohack/mbf.dh"

    Adds ammo, state, weapon slot, thing slot, and string mnemonics for 
    MBF-compatible ports, plus the "using mbf" line. Also adds ZDoom thing 
    and weapon aliases.

#include <extended>
#include "classpath:decohack/extended.dh"

    Adds ammo, state, weapon slot, thing slot, and string mnemonics for 
    Extended-DEH-compatible ports, plus the "using extended" line, AND 
    freeing up the extra extended states immediately for use, AND freeing 
    the things from 151 to 250 (the extended things) for auto-thing fill.
    Also adds ZDoom thing and weapon aliases.

#include <mbf21>
#include "classpath:decohack/mbf21.dh"

    Adds ammo, state, weapon slot, thing slot, and string mnemonics for 
    MBF21-compliant ports (which includes Extended-DEH), plus the 
    "using mbf21" line, AND freeing up the extra extended states 
    immediately for use, AND freeing the things from 151 to 250 (the
    extended things) for auto-thing fill. Also adds ZDoom thing and
    weapon aliases.

#include <dsdhacked>
#include "classpath:decohack/dsdhacked.dh"

    Adds ammo, state, weapon slot, thing slot, and string mnemonics for 
    DSDHACKED-compliant ports (which includes MBF21), plus the 
    "using dsdhacked" line, AND freeing up the states from 1100 to the
    state max, freeing the things from 151 to the thing max for 
    auto-thing fill, and allows new sound and sprite definitions 
    automatically. Also adds ZDoom thing and weapon aliases.

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

#include <friendly>
#include "classpath:decohack/constants/friendly_things.dh"

    "Friendly" names for Doom things, all the way up through extended.

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

#include "classpath:decohack/constants/doom19.dh"

    All ammo, state, weapon slot, thing slot, and string mnemonics for Doom 
    1.9 EXEs.

#include "classpath:decohack/constants/doom19/ammo.dh"

    All ammo slot mnemonics for Doom 1.9 EXEs.

#include "classpath:decohack/constants/doom19/states.dh"

    All state mnemonics for Doom 1.9 EXEs.

#include "classpath:decohack/constants/doom19/things.dh"

    All thing slot mnemonics for Doom 1.9 EXEs.

#include "classpath:decohack/constants/doom19/things_aliases.dh"

    All thing aliases for Doom 1.9 EXEs.

#include "classpath:decohack/constants/doom19/weapons.dh"

    All weapon slot mnemonics for Doom 1.9 EXEs.

#include "classpath:decohack/constants/doom19/weapons_aliases.dh"

    All weapon aliases for Doom 1.9 EXEs.

#include "classpath:decohack/constants/doom19/strings.dh"

    All string mnemonics for Doom 1.9 EXEs.

#include "classpath:decohack/constants/udoom19.dh"

    All ammo, state, weapon slot, thing slot, and string mnemonics for 
    Ultimate Doom 1.9 EXEs (Doom 1.9 ammo, thing, weapon, and states are 
    reused).

#include "classpath:decohack/constants/udoom19/strings.dh"

    All string mnemonics for Ultimate Doom 1.9 EXEs.

#include "classpath:decohack/constants/boom.dh"

    All ammo, state, weapon slot, thing slot, and string mnemonics for 
    Boom-compatible ports.

#include "classpath:decohack/constants/boom/states.dh"

    All state mnemonics for Boom-compatible EXEs.

#include "classpath:decohack/constants/boom/strings.dh"

    All string mnemonics for Boom-compatible EXEs (meant to be a common
    define for both Doom indices and Boom string keys).

#include "classpath:decohack/constants/boom/things.dh"

    All thing mnemonics for Boom-compatible EXEs.

#include "classpath:decohack/constants/boom/things_aliases.dh"

    All thing aliases for Boom-compatible EXEs.

#include "classpath:decohack/constants/mbf.dh"

    All ammo, state, weapon slot, thing slot, and string mnemonics for 
    MBF-compatible ports.

#include "classpath:decohack/constants/mbf/states.dh"

    All state mnemonics for MBF-compatible EXEs.

#include "classpath:decohack/constants/mbf/things.dh"

    All thing mnemonics for MBF-compatible EXEs.

#include "classpath:decohack/constants/mbf/things_aliases.dh"

    All thing aliases for MBF-compatible EXEs.

#include "classpath:decohack/constants/extended.dh"

    All ammo, state, weapon slot, thing slot, and string mnemonics for 
    Extended-DEH-compatible ports.

#include "classpath:decohack/constants/extended/states.dh"

    All state mnemonics for Extended-DEH-compatible EXEs.

#include "classpath:decohack/constants/extended/things.dh"

    All thing mnemonics for Extended-DEH-compatible EXEs.

		

CHANGELOG

### Changed for 0.35.0

* `Fixed` Soulsphere health misc value did not check the correct property range.
* `Changed` Some Thing bit documentation for Doom19.
* `Changed` Speed on MISSILE Things can now take an explicit fixed-point value (instead of a coerced one).
* `Changed` Thing Health property can go up to a max integer value.
* `Changed` Thing Damage property can go up to an integer value.
* `Changed` Ammo max and pickup properties can go up to a max integer value.
* `Changed` State duration property can go up to an integer value.


### Changed for 0.34.0

* `Fixed` Any clause that sets intervals (freeing things, protecting states) may create a condition that causes an endless loop. (Issue. #119)
* `Fixed` Sound entries were off by 1 due to a misunderstanding of what index sound entries started at. (Issue #120)


### Changed for 0.33.0

* `Added` `set next` clauses for manipulating the next sprite or sound index used in DSDHACKED patches. (Enh. #116)
* `Added` `set next` clause for manipulating the next thing index used in `auto thing`.


### Changed for 0.32.2

* `Fixed` CLEAR STATES in an Each Thing clause did not clear states. (Issue #115)
* `Fixed` CLEAR STATES in an Each Weapon clause did not clear states.


### Changed for 0.32.1

* `Fixed` Mass on Things can be negative, for real this time. (Issue #114)


### Changed for 0.32.0

* `Fixed` [GUI] Some autocomplete docs fixes/changes.
* `Added` Added more valid string mnemonics to Boom patches (notably, Woof/ZDoom obituaries).

### Changed for 0.31.2

* `Added` `TRANSLATION1` as a valid bit flag for Things.


### Changed for 0.31.1

* `Fixed` The Soulsphere, Megasphere, Blur Sphere, and Invulnerability didn't have their `TRANSLUCENT` flag set. (Issue #112)


### Changed for 0.31.0

* `Fixed` [GUI] Editor would error out on workspace load with no files open.
* `Added` A warning for when a user makes a Thing that is `SHOOTABLE` with 0 mass. (Enhancement #103)
* `Changed` Slightly improved some error messages.

### Changed for 0.30.4

* `Fixed` `Fast` and other MBF21 flags were not being respected in state bodies. (Issue #95)


### Changed for 0.30.3

* `Fixed` If DroppedItem was the only change to a Thing, it would not be saved in the patch. (Issue #91)


### Changed for 0.30.2

* `Fixed` Mass on Things can be negative. (Issue #90)


### Changed for 0.30.1

* `Fixed` Macros for `STR_PD_YELLOWK` and `STR_PD_REDK` were swapped (in doom19 and udoom19), plus `MTF_SHOTGUNGUY_DEAD` was added. (Issue #85)


### Changed for 0.30.0

* `Fixed` MBF21 pointer `A_ConsumeAmmo` had an incorrect signature/documentation, despite it compiling properly. (Issue #84)


### Changed for 0.29.0

* `Added` `monstersFightOwnSpecies` miscellany field. (Enhancement #82)


### Changed for 0.28.0

* `Added` Documentation for all pointers in is HTML when dumped with `--dump-pointers-html`.


### Changed for 0.27.0

* `Added` The `state protect` and `state unprotect` clauses now accept state index clauses, not just numbers. (Enhancement #12)
* `Added` Custom properties. (Enhancement #55, #54)


### Changed for 0.26.0

* `Fixed` Added some bit flags that were missing from the docs: UNUSEDX bits, FRIENDLY.
* `Added` A directory tree for the GUI.
* `Added` A warning on wrong int/fixed type use (Enhancement #78).
* `Added` A warning on wrong Thing type use (MISSILE vs. not) (Enhancement #77).


### Changed for 0.25.0

* `Fixed` Changed the z-position parameter type for MBF's A_Spawn pointer to "fixed".
* `Fixed` Changed the range parameter type for MBF21's A_MonsterMeleeAttack pointer to "fixed".
* `Fixed` Some inconsistent error messages around flag setting/removal.
* `Fixed` Thing `dropitem` didn't allow 0 as a viable value.
* `Added` The DECOHack GUI, plus a switch to start it (`--gui`).
* `Added` Documentation for all pointers when dumped with `--dump-pointers`.
* `Added` A `--charset` switch for specifying the encoding of the input source files (if not system default).
* `Added` The ability to write the patch and the source directly into a WAD.
* `Changed` MBF's A_FireOldBFG pointer should have been a weapon pointer instead of a thing pointer.
* `Changed` Added a better error message for bad action pointers.
* `Changed` Added an error message if the user does "flag mixing" on the same expression (see Issue #76).


### Changed for 0.24.1

* `Fixed` MBF Action Pointers were not recognized. This has been fixed.
* `Fixed` An error is now thrown if you are attempting to define a custom action pointer that already exists.


### Changed for 0.24.0

* `Added` The ability to read a DECOHack patch from STDIN.
* `Added` The ability to add custom action pointers. (Enhancement #72)


### Changed for 0.23.0

* `Added` A patch format for the Unity port, `doomunity`, which is `udoom19` but with no string limits (thanks, Xaser!). (PR #65).
* `Added` A way to dump all known action pointers to DECOHack to STDOUT via the `--dump-pointers` runtime switch.
* `Fixed` MBF21's `A_SeekTracer` parameters needed to check for FIXED angles, not UINT.
* `Fixed` Some Action Pointer parameter interpretation - if a field needs a fixed expression, integer values are coerced to fixed, and vice-versa.
* `Changed` Stricter (but safer) checking for types in parameters, such as Fixed values, and auto-detecting sounds, things, and states.
* `Changed` Better string length error messages (Issue/Enhancement #64).


### Changed for 0.22.0

* `Fixed` **MAJOR FIX** DECOHack was completely broken and would NPE out on any parse. Whoops. Fixed!


### Changed for 0.21.0

* `Added` STR_ `#defines` for BOOM's extended locked door strings were missing (thanks, Xaser!). (PR #61)
* `Changed` A_RandomJump and A_WeaponJump should take a UINT, not BYTE for probability (thanks, Altazimuth!). (Issue #62)


### Changed for 0.20.1

* `Fixed` Extended sounds were off by 1. (Issue #60)


### Changed for 0.20.0

* `Added` Multiple input files can be added, parsed in the order provided. (Enhancement #57)
* `Fixed` Bad tokens in action pointer blocks no longer hang the parser. (Issue #59)


### Changed for 0.19.2

* `Fixed` Changed maximum string lengths for Vanilla patches (doom19, udoom19). (Issue #56)


### Changed for 0.19.1

* `Fixed` Thing indices were not being parsed properly in action pointer parameters.


### Changed for 0.19.0

* `Fixed` `A_JumpIfHealthBelow` did not accept negative values for the health reference value. (Issue #53)
* `Fixed` Actor label values were not backfilled properly if the action that used them needed applying to many frames on one line.
* `Added` Auto-things and free-able things (all patches). (Enhancement #50)
* `Added` Aliases for things and weapons via `alias thing` and `alias weapon` statements.
* `Added` DSDHACKED patch support. (Enhancement #42)


### Changed for 0.18.1

* `Fixed` Editor keys were not being saved if a Thing body didn't have 
  parse-able content right after body start.
* `Changed` Copying a definition from the exact same one will not perform a copy,
  as there is nothing to do.


### Changed for 0.18.0

* `Added` Support for editor keys on Things like DECORATE. (Enhancement #47)


### Changed for 0.17.0

* `Added` Labels can now be used pre-declared in actor (thing/weapon) definitions. (Enhancement #35)
* `Added` Some keywords/delimiters to force interpretation of some action pointer parameters.
* `Added` The output source switch for outputting the combined source into one file.
* `Fixed` Some "next state" clauses did not throw errors properly in state blocks.
* `Changed` The budget output does not output the action pointer budget if the patch in Boom format or higher.


### Changed for 0.16.2

* `Fixed` The "Red Skull" pickup string should be `GOTREDSKULL`, with two Ls.
* `Changed` An error is now thrown if a string name is invalid (Boom and higher).


### Changed for 0.16.1

* `Fixed` Things did not have TRANSLUCENT set. (Issue #41)
* `Fixed` NPE on actorless state fill.


### Changed for 0.16.0

* `Changed` Label-Goto-Label syntax in state bodies now supported. (Issue #37)


### Changed for 0.15.0

* `Changed` Altering a state directly now removes its "free" status, if set.
* `Changed` Thing speed now accepts negative values.


### Changed for 0.14.1

* `Fixed` Lexer bugfix. Fixes inconsistent identifier concatenation. (Issue #32)


### Changed for 0.14.0

* `Added` Each Thing/Weapon Characteristics Filling. (Enhancement #24)
* `Added` Individual state property changes.
* `Fixed` A_AddFlags, A_RemoveFlags, A_JumpIfFlagSet used the wrong parameter type.


### Changed for 0.13.0

* `Added` Multi-action pointer lines. (Enhancement #16)


### Changed for 0.12.0.1

* `Added` Missing docs for `ammopershot` weapon field.


### Changed for 0.12.0

**Major compiler change. Do not use numbers for your sound definitions and references!**

* `Added` Pre-emptive weapon flag checking on non-MBF21 patches.
* `Fixed` Weapon MBF21 flags were parsed incorrectly.
* `Fixed` Ensure blank files are written when no changes are made.
* `Changed` Sounds definitions now REQUIRE a name, not a number.
* `Changed` Some internal sound index/position handling to align with Doom internals rather than DeHackEd's mishandling of sound definitions.


### Changed for 0.11.2

* `Fixed` Extended (and higher) sound slots were not accessible via definition. (Issue #29)
* `Fixed` NPE if no state clauses between labels. (Issue #28)


### Changed for 0.11.1

* `Fixed` Flag detection priority.
* `Fixed` Splashgroup Outputs as Projectilegroup (Issue #27)
* `Fixed` Melee range not being written correctly (Issue #25)
* `Fixed` State search looped indefinitely if starting index was 0 with no free states. (Issue #26)
* `Fixed` Thing speed info being written on no change.
* `Changed` An error message for valid states.


### Changed for 0.11.0

* `Added` Missing DEHEXTRA thing fields and MBF21 support.
* `Added` Correct action pointer use detection on things and weapons.
* `Added` A way to combine flags per function pointer parameter.
* `Added` `#include` directive aliases for convenience.
* `Fixed` Sound indices for function calls were off by 1.
* `Fixed` Megasphere health misc entry was not parsed! Whoops!
* `Fixed` Megasphere health not initialized, either!


### Changed for 0.10.1

* `Fixed` The background flat string indices in the constants files were incorrect.


### Changed for 0.10.0

* `Added` An index value clause for sound indices on parameters.


### Changed for 0.9.0

* `Changed` Handling of protected states - protected states are never treated as free, and cannot be altered directly.


### Changed for 0.8.0

* `Fixed` Parsing a single state body with just the next frame clause did nothing. (Issue #10) (thanks, Aurelius!)
* `Fixed` Certain non-blank DEH Extended states were not accessible.
* `Added` Ability to clear single states or labels on things and weapons. (Issue #11)
* `Changed` `S_FREE_START` in `classpath:decohack/constants/extended/states.dh` is now 1100.


### Changed for 0.7.0

* `Fixed` Disallow MBF action pointers in non-MBF patches.
* `Added` Support for using the "unused" state parameters as offsets (supported in Doom code). (Issue #9)


### Changed for 0.6.1

* `Fixed` Changed file export for compatibility with Java 8.


### Changed for 0.6.0

* `Added` Better state referencing.


### Changed for 0.5.0

* `Added` Support for DEHExtra sound definitions (thanks @XaserAcheron).
* `Fixed` Better support for DEHExtra in general and code refactoring to accommodate.


### Changed for 0.4.1

* `Fixed` Changed "Friendly" things constants (`classpath:decohack/constants/friendly_things.dh`).
* `Changed` Updated help.


### Changed for 0.4.0

* `Added` "Friendly" things constants (`classpath:decohack/constants/friendly_things.dh`).
* `Added` Parser: Set weapon/thing states using other weapon/thing states.


### Changed for 0.3.0

* Initial Release.