// Header for implementing behaviors
// Very early draft 1/24/00 by eris

// I am certain this will change, so don't go nuts writing behaviors
// but the basic layout should remain similar...

// This header should not be modified, as its used in the bot core as well

// Things in particular you shouldn't add because they'll be added to the
// bot core:

// Commands: I plan to parse commands in the core so every behavior won't
// repeat the same work. This will also include some sort of help system.

// BotOp: The BotOp password, etc. will be handled in the core.

// Info: *info will be handled by the core (at the behavior's request) so
// the data is easily managed and multiple behaviors don't *info the same
// person over and over... (unless they need an updated lag report or
// something)

// Ignoring: I will provide an ignore feature the behaviors can call. It
// will have 2 modes, loose and strict. Loose is just ignore by name, while
// strict will ignore by name, IP, and machine ID.


// -- snip -- Code starts here

#ifndef BOT_H
#define BOT_H

// this is the only function a behavior has to implement:
// extern "C" __declspec (dllexport) void CALLBACK BOT_Cmd(BOTCMD *bc);


#define MAXUSERS 500
#define MAXBEHAVIORS 50

typedef struct {
  // This data should always be accurate
  char   Name[32];
  char   Squad[32];      //nyi
  int    Wins;           //nyi
  int    Losses;         //nyi
  int    Points;         //nyi
  int    Rating;         //nyi

  char   Lastship;       // 1-8 for ships, 0 for spec - Only valid on
                         // BOTCMD_ShipChange
  char   Shiptype;       // 1-8 for ships, 0 for spec
  
  // This data is updated only periodically when requested
  // and should only be used in response to MSG_SPECINFO
  short  Bounty;         //nyi
  int    XCoord;         //nyi
  int    YCoord;         //nyi
  char   ShipDirection;  //nyi
  short  Energy;         //nyi
  char   Flags;          //nyi
  char   HasBall;        //nyi

  // This data is updated only periodically when requested and should be used
  // only in response to MSG_USERINFO. Some of the info like IP and MID
  // will remain constant if looked at even once, so IsKnown is set to true
  // if we have this info...
  char   IsKnown;        //nyi
  int    MID;            //nyi
  short  LastFreq;       // Only valid on BOTCMD_FreqChange
  short  Freq;
  char   IP[16];         //nyi
  short  AvePing,CurPing,MinPing,MaxPing;  //nyi
  short  S2CPloss,C2SPloss; //nyi
  // *todo* There's plenty of other info in a *info we can grab

  // This field is updated whenever this structure is sent to a behavior
  // and is read and stored upon return. It is the only data field that
  // is not read only. A behavior may ignore this, or use it however it
  // wants to store data.
  void*  Ptr;

  // This data is for internal use and should not be messed with at all.
  char   IsValid;
  short  UID;
  char   SpecCnt;                  //nyi
//char   SpecList[MAXBEHAVIORS];   //nyi
  char   InfoCnt;                  //nyi
//char   InfoList[MAXBEHAVIORS];   //nyi
  int    PtrList[MAXBEHAVIORS];    //nyi
  char   IsBotOp;                  //nyi
  short  IgnoreTime;               // in minutes      // nyi
  int    IgnoredAt;                //nyi

} USER_DATA;



typedef struct {
  int   Msg;           // One of the #define BOTMSG_

///// used for BOTMSG_Line ////////////////////////////////////////////////////
  short uid;           // user ID if its a private message
  short LineType;      // Line Type
  char  *Line;         // pointer to text
  char  Sound;         // 0 for no sound, otherwise sound #

///// used for BOTMSG_Register ////////////////////////////////////////////////
  char *Cmd;           // String of command including !
  char OpOnly;         // Is the command for ops only?
  char *HelpFile;      // Help Filename for this command
  int  CmdID;          // CmdID - The bot core doesn't care about this,
                       // the behavior should use it to uniquely identify
                       // this command.

} BOTMSG;

typedef struct {
  int Cmd;  // One of the #define BOTCMD_

///// used for BOTCMD_Init ////////////////////////////////////////////////////
  HWND hwnd;   // Window handle to send messages
  char BehaviorID;  // Your Behavior's ID, save this, you need to send it
                    // with every BOT_MSG

///// used for all commands that have user data (except kills) ////////////////


  // This is read only with the single exception of Ptr, which
  // is a Ptr to info for this user for this behavior. Ptr is
  // maintained independantly for each behavior and may contain
  // anything the behavior wants    
  USER_DATA *UserData;

///// used for BOTCMD_Kill ////////////////////////////////////////////////////
  USER_DATA *Killed;
  USER_DATA *Killer;
  short     Bounty;

///// used for BOTCMD_Line ////////////////////////////////////////////////////
  char  *Line;
  short LineType;   // see #define LINETYPE_

///// used for BOTCMD_Cmd /////////////////////////////////////////////////////
  char *CmdStr;  // the text of the command - should use CmdID, its faster
  char *Params;  // parameters of the command
  int  CmdID;    // the command ID the behavior registered for this command

///// used for all commands except BOTCMD_Init ////////////////////////////////

  USER_DATA *UserList;   // This is the list of all users.
                         // Its an array of USER_DATA of size MAXUSERS.
                         // Only records with UserList[i].IsValid==TRUE
                         // are valid users. ALL THIS DATA IS READ ONLY
                         // AND ONLY ACCURATE FOR THIS MESSAGE. COPY
                         // ANYTHING YOU NEED LONG TERM.



} BOTCMD;


// To send messages to the bot, use SendMessage with a message of WM_BOT,
// wparam set to your BotID, and lparam set to the pointer to the message.
// DO NOT USE POSTMESSAGE. The message structure is copied and may be
// reused after SendMessage has completed

#define WM_BOT            0x423
#define BOTMSG_Line       0  // Send a message
#define BOTMSG_Register   1  // Register a command
#define BOTMSG_LineSound  2  // Send a message with a sound

#define BOTCMD_Init       0
#define BOTCMD_Entered    1
#define BOTCMD_Left       2
#define BOTCMD_Kill       3
#define BOTCMD_Line       4
#define BOTCMD_Shutdown   5
#define BOTCMD_Command    6
#define BOTCMD_Arena      7  // changing arenas, forget everything you know
                             // Arena name is in "Line" and is "" for pub
#define BOTCMD_Tick       8  // called every 50ms or so
#define BOTCMD_Shipchange 9
#define BOTCMD_FreqChange 10

// *todo* chat, squad, rederror
#define LINETYPE_Pub         2
#define LINETYPE_Macro       1
#define LINETYPE_Team        3
#define LINETYPE_AnyTeam     4
#define LINETYPE_Private     5
#define LINETYPE_CrossZone   7  // does not have user data
#define LINETYPE_Arena       0  // does not have user data
#define LINETYPE_Chat        9  // does not have user data
#define LINETYPE_SysopMsg    8  // does not have user data

#endif
