// Some preliminaries on the structure of the MTBL (Mission TaBLe) chunk.
//
// Written by Eric C. Peterson, licensed under UoI/NCSA.
// Revision history:
// 	+ 2009 May 11 : Initial release

// note: if the id is set to -1 no sound gets played
typedef struct {
    short id;
    char filename[9];
} PRJPointer;

// there are missing flags here, maybe the engine is capable of some wacky
// things that didn't make it into the game?
typedef enum {
    NONE    = 0x00000000,
    DESTROY = 0x00000002,   // succeed if the target is destroyed
    DEFEND  = 0x00000004,   // fail if the target is destroyed
    INSPECT = 0x00000008,   // succeed when you inspect the target
    BEGIN   = 0x00000010,   // this always seems to kick off the table
    GOTO    = 0x00000100,   // succeed when you reach the target
    WAIT    = 0x00000200,   // this is used to collect subobjectives
    SLEEP   = 0x00000400,   // so is this
    LEAVE   = 0x00002000,   // succeed when you move too far from the target

    MISSION_SUCCEED     = 0x00010000,   // if this succeeds, win the mission
    MISSION_FAIL        = 0x00020000,   // if this succeeds, lose the mission
    OBJECTIVE_SHOW      = 0x00040000,   // when this succeeds, make the target
                                        // objective visible
    OBJECTIVE_FAIL      = 0x00080000,   // when this succeeds, mark the target
                                        // objective failed
    OBJECTIVE_SUCCEED   = 0x00100000,   // when this succeeds, mark the target
                                        // objective successful
} ObjectiveKind;

typedef struct {
    // set these all to -1 if you don't plan on using this precondition
    char state; // this char controls what the game state has to be for this
                // recondition to be marked as cleared
                //  'C'omplete means the objective depends upon some actual
                //  game status, like killing something or tagging a nav point
                //  'S'ucceed means that the objective referred to by the next
                //  two bytes has to be marked as 'succeeded'
                // 'F'ail is dual to Succeed
                // 'I'ncomplete is dual to Complete
    char objective;     // objective the action refers to
    char mission_tbl;   // mission table the objective is in (i.e., which star
                        // controls the objective)
    char pad; // round it off to 4 bytes
} Precondition;

typedef struct {
    // header
    ObjectiveKind kind;
    char visibility; // 'V'isible, 'H'idden, dictates HUD appearance
    char pad;        // we don't want the visibility char to get lonely :(

    // precondition block
    int isConjunction; // if this is nonzero, _all_ the preconditions have to be
                       // satisfied before this objective can change state
    Precondition preconditions[8];

    // other data about the objective
    int time;         // again in seconds
    char i_dunno_1;   // this seems to be related to have important the
                      // objective is, but i can't find any consistent use of it
    char criticality; // 'O'ptional, 'M'andatory
    char i_dunno_2;   // this always seems to be zero, but it's in a weird
                      // place for padding, so... :/
    char i_dunno_3;   // this _usually_ is zero.  i've seen nonzero, but i
                      // can't tell what it does.  seems to be related to how
                      // easy it is to distract an enemy?  maybe?

    // sounds
    PRJPointer success; // when this objective completes successfully,
                        // play this sound
    PRJPointer failure; // when this objective completes unsuccessfully,
                        // play this sound

    // target data
    PRJPointer target; // what this objective is "about"
    short target_mission_slot;   // if the kind field is one of the OBJECTIVE*
                                 // enums, then this is the mission table we're
                                 // going to modify
    short target_objective_slot; // ditto for the objective index we're going
                                 // to modify

    // and more data
    char description[64]; // shows up in the HUD
} Objective;

typedef struct {
    char header[4]; // 'M', 'T', 'B', 'L'
    long size; // including the header and everything, total chunk size
    long star; // declare which star these objectives apply to
    long time; // time in seconds for the mission to be successfully completed
    PRJPointer success_sound; // this sound gets played when you complete the
                              // mission successfully
    PRJPointer failure_sound; // and this one gets played when you fail
    Objective objectives[];   // the number of objectives can be calculated from
                              // the size field
} MTBLChunk;
