/*

    Unnamed MUD Project
    version: Alpha (August 13, 2010)
    by Varkalas D`Lonovan


    TODO List
    *********

    - implement the methods for attacking
        * [in_progress] calculate attack speed
        * [in_progress] calculate chance to hit
        * [in_progress] calculate avoidance
            - [ ] evasion
            - [ ] parrying
            - [ ] blocking
        * [ ] calculate damage modifiers
        * [ ] calculate damage reduction modifiers
        * [ ] calculate recovery
        * [ ] add an additional parameter to attack specific locations on an enemy
    - add basic AI to a creature in the test room (creature attacking & moving)
    - A.I. creature_move
        * remove creature from list in the room from the world
        * move the creature to next room
        * change pointer to the current room for the creature
        * add creature to list in the new room from the world
    - implement fatigue recovery and wound recovery
    - look command needs to be more advanced (look in bag, look at sword in sheath)
    - modify output still needs work:
        * Mac friendly--line end, Windows: \r\n, Unix: \n, Mac: \r
        * still doesn't ignore carriage returns, spaces, tabs, and newlines when
          considering the size of the string for word wrapping
    - simple world editor... makes world files for the server to read in
    - switch on over to sockets!  make this bad boy multiplayer
        * the GUI will need to turn into the client, only code that will be there
          is stuff to send shit through the socket to the server, and receive and
          display (word wrap stays on the client side)
        * the server will be most of the code that's already there, just instead
          of output() we will be sending it to the player's socket
 
    (considerations)

    - making an outputln function to compliment output
    - should an accumulator be implemented in conjunction with the timer?  this may
      only be necessary in displaying graphics... look into it
    - possibly redesign the process for calling commands
        * currently:  process_input modifies the input string so it's the
                      parameters that follow the command the user inputs.
                      it then returns which command was given, and the
                      main loop calls the respective function
        * options:  remove process_input all together, have that code be
                    inside the main loop
    - when we start using sockets, look into select() as opposed to poll() for input


    History
    *******

    September 1, 2011
    - fixed the creature spawning/despawning

    August 13, 2011
    - implemented a creature despawning system (needs more work)
    - modified the spawning system to operate more smoothly

    August 13, 2011
    - implemented ordinal syntax for all commands
    - updated the look command to include "in" and "at"
    - took care of a bunch of TODO's
    - updated many commands with fixes & making future changes easier

    August 12, 2011
    - updated the health command

    December 2, 2010
    - implemented the health command
    - added ordinal syntax (first, second, other, etc.) to the wear command
    - updated the look command

    March 20, 2010
    - implemented the following commands:
        * swap
        * look

    March 16, 2010
    - implemented a creature spawning system
    - client now follows the text as it is being displayed
    - implemented a low resolution timer in case high res fails

    March 10, 2010
    - upgraded the program from a console application to Win32 GUI
        * now the user input is on a separate thread and thus the time for a game
          cycle can be accurately gauged (previously it would hang on the function
          call that gets the user's input during every cycle of the game loop)
        * input and output functionality has been re-established with the GUI
        * the output and command functions were modified and now take in a handle
          to the edit box window that displays the output (temporary)
    - implemented a high resolution timer
    - modified the output text and word wrapping

    March 7, 2010
    - implemented the following commands:
        * inventory
        * wear
        * equipment
    - implemented a nifty word wrapping algorithm
    - user input processing is fully functional

*/



#ifndef UNTITLED_H
#define UNTITLED_H



/*  Include Header Files
    ************************************************************************ */

#include <stdio.h>      /* input/output */
#include <stdlib.h>     /* random number generation */
#include <time.h>       /* used as a seed for random numbers */
#include <ctype.h>      /* converting characters to upper/lower case */
#include <stdarg.h>     /* variable arugments */
#include <string.h>     /* string functions */
#define WIN32
#ifdef WIN32
#include <windows.h>    /* high resolution timer for Windows */
#else
#include <sys/time.h>   /* high resolution timer for Unix */
#endif



/*  Standard Definitions
    ************************************************************************ */

#ifdef DEBUG
#undef DEBUG
#endif
#define DEBUG 1

#ifndef BOOL
#define BOOL int
#endif



/*  Constants and Enumerations
    ************************************************************************ */

enum { LOW_RESOLUTION_TIMER = FALSE };
enum { USER_INPUT_MAX_LENGTH = 16384 };
enum { KEYWORD_MAX_LENGTH = 256 };
enum { DESCRIPTION_MAX_LENGTH = 1024 };
enum { WORD_WRAP = 100 };
enum { OUTPUT_MAX_LENGTH = 262144 };

typedef enum
{
    NO_COMMAND,
    COMMAND_QUIT,
    COMMAND_INVENTORY,
    COMMAND_EQUIPMENT,
    COMMAND_WEAR,
    COMMAND_REMOVE,
    COMMAND_ATTACK,
    COMMAND_SWAP,
    COMMAND_SIT,
    COMMAND_STAND,
    COMMAND_HELP,
    COMMAND_LOOK,
    COMMAND_HEALTH
} Command_Type;

typedef enum
{
    PLAYER,
    OTHER_PLAYER,
    CREATURE
} Creature_Type;

typedef enum
{
    GENERAL,
    ARMOR,
    WEAPON,
    USABLE,
    QUEST
} Object_Type;

typedef enum
{
    /* general */
    NONE,
    ACCESSORY,
    CONTAINER,
    /* armor */
    CLOTH,
    LEATHER,
    MAIL,
    WOOD,
    BONE,
    PLATE,
    SHIELD,
    /* weapons */
    UNARMED,
    ONE_HANDED_SLASH,
    ONE_HANDED_BLUNT,
    ONE_HANDED_PIERCING,
    TWO_HANDED_SLASH,
    TWO_HANDED_BLUNT,
    TWO_HANDED_PIERCING,
    POLEARM,
    STAFF,
    THROWING,
    BOW,
    CROSSBOW,
    /* usable */
    USE,
    USE_NO_PICK_UP
    /* quest */
} Object_Subtype;

typedef enum
{
    TINY,
    SMALL,
    MEDIUM,
    LARGE,
    GIANT
} Size;

typedef enum
{
    HEAD,
    FACE,
    NECK,
    SHOULDERS,
    TORSO,
    BACK,
    ARMS,
    HANDS,
    WAIST,
    LEGS,
    FEET
} Location;



/*  Structures
    ************************************************************************ */

/* type definitions */
typedef struct Command Command;
typedef struct Room Room;
typedef struct Adjacent_Room Adjacent_Room;
typedef struct String_List String_List;
typedef struct Spawn_Group Spawn_Group;
typedef struct Skill Skill;
typedef struct Creature Creature;
typedef struct Condition Condition;
typedef struct Item Item;

struct Command
{
    char *       name;
    Command_Type command;
};

struct Room
{
    char            name[KEYWORD_MAX_LENGTH];
    char            description[DESCRIPTION_MAX_LENGTH];
    Adjacent_Room * adjacent_rooms;
    Spawn_Group *   spawns;
    int             spawn_limit;
    int             number_of_spawns;
    Creature *      players;
    Creature *      creatures;
    Item *          items;
    Item *          usable_objects;

    Room *     next;
};

struct Adjacent_Room
{
    String_List * keywords;
    Room * room;

    Adjacent_Room * next;
};

struct String_List
{
    char string[KEYWORD_MAX_LENGTH];

    String_List * next;
};

struct Spawn_Group
{
    char   creature_name[KEYWORD_MAX_LENGTH];
    short  current_num_spawns;
    short  max_spawns;
    double time_to_spawn;
    double time_to_live;
    double spawn_timer;
    float  spawn_probability;

    Spawn_Group * next;
};
/*
struct Skill
{
    char  name[KEYWORD_MAX_LENGTH];
    float rank;
    char  description[DESCRIPTION_MAX_LENGTH];
};*/

struct Creature
{
    /* basic information */
    char          name[KEYWORD_MAX_LENGTH];
    char          description[DESCRIPTION_MAX_LENGTH];
    String_List   spawn_text[KEYWORD_MAX_LENGTH];
    String_List   death_text[KEYWORD_MAX_LENGTH];
    String_List   attack_text[KEYWORD_MAX_LENGTH];
    Creature_Type type;
    Size          size;
    float         weight;
    Room *        location;
    float         time_to_live;
    float         time_alive;

    /* attributes */
    short strength;
    short dexterity;
    short constitution;
    short will;
    short acuity;
    short memory;
    short charisma;

    /* health */
    float max_endurance;
    float endurance;
    float vitality;
    float scalp;
    float forehead;
    float left_ear;
    float right_ear;
    float left_eye;
    float right_eye;
    float nose;
    float lips;
    float left_cheek;
    float right_cheek;
    float chin;
    float jaw;
    float neck;
    float left_shoulder;
    float right_shoulder;
    float chest;
    float back;
    float butt;
    float abdomen;
    float groin;
    float left_bicep;
    float right_bicep;
    float left_forearm;
    float right_forearm;
    float left_wrist;
    float right_wrist;
    float left_elbow;
    float right_elbow;
    float left_dorsal;
    float right_dorsal;
    float left_palm;
    float right_palm;
    float left_fingers;
    float right_fingers;
    float left_thumb;
    float right_thumb;
    float left_thigh;
    float right_thigh;
    float left_calf;
    float right_calf;
    float left_knee;
    float right_knee;
    float left_shin;
    float right_shin;
    float left_ankle;
    float right_ankle;
    float left_heel;
    float right_heel;
    float left_midfoot;
    float right_midfoot;
    float left_toes;
    float right_toes;

    /* items */
    Item * right_held;
    Item * left_held;
    Item * inventory;
    Item * equipment;

    /* combat variables */
    float balance;          /* -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5 */
    short engaged_enemies;  /* number of enemies the creature is engaged with */

    /* offensive skills */
    float unarmed;
    float one_handed_slash;
    float one_handed_blunt;
    float one_handed_piercing;
    float two_handed_slash;
    float two_handed_blunt;
    float two_handed_piercing;
    float polearms;
    float staves;
    float throwing;
    float bows;
    float crossbows;
    float bash;
    float backstab;
    float dual_wielding;
    float double_attack;
    float disarm;

    /* defensive skills */
    float unarmored_resistance;
    float cloth_armor;
    float leather_armor;
    float mail_armor;
    float wooden_armor;
    float bone_armor;
    float plate_armor;
    float evasion;
    float blocking;
    float parrying;
    float multiple_opponents;

    /* survival skills */
    float foraging;
    float perception;
    float stealing;
    float climbing;
    float swimming;
    float skinning;
    float hiding;
    float sneaking;
    float tracking;
    float lockpicking;
    float disarming;
    float bandaging;
    float bartering;
    float appraisal;

    /* trade skills */
    float alchemy;
    float baking;
    float brewing;
    float carving;
    float fishing;
    float fletching;
    float jewelcraft;
    float pottery;
    float smithing; /* (armorcraft/weaponcraft) */
    float tailoring;

    int is_attacking;

    /* part of multiple creatures in a room */
    Creature * next;
};

struct Condition  /* item health status */
{
    float head;
    float ears;
    float face;
    float jaw;
    float neck;
    float left_shoulder;
    float right_shoulder;
    float chest;
    float abdomen;
    float groin;
    float back;
    float buttocks;
    float left_bicep;
    float right_bicep;
    float left_forearm;
    float right_forearm;
    float left_wrist;
    float right_wrist;
    float left_hand;
    float right_hand;
    float left_leg;
    float right_leg;
    float left_foot;
    float right_foot;
};

struct Item
{
    /* basic information */
    char           name[KEYWORD_MAX_LENGTH];             /* keyword */
    char           description[DESCRIPTION_MAX_LENGTH];  /* what the user sees */
    Object_Type    type;                                 /* the item type */
    Object_Subtype subtype;                              /* the item type (more specific) */
    Size           size;                                 /* factor for combat modifiers */
    float          weight;                               /* factor for encumbrance (worn/armor) and damage (weapon) */
    float          quality;                              /* construction quality */
    Condition      condition;                            /* condition status */

    /* worn item factors */
    Location location;               /* where the item is worn */
    int      occupance;              /* measure of space that the item takes up */
    Item *   contents;               /* items inside the item (if it's a container) */

    /* armor factors */
    float protection;                /* protection level */
    float absorption;                /* absorption factor */
    float hindrance;                 /* maneuvering hindrance */

    /* weapon factors */
    float slashing_damage;
    float blunt_damage;
    float piercing_damage;

    /* part of the inventory or equipment */
    Item * next;
};



/*  Function Prototypes
    ************************************************************************ */

/* command.c */
void output ( HWND window, const char * string, ... );
Command_Type process_input ( char * string );
void command_quit ( HWND window, Creature * creature );
void command_inventory ( HWND window, const Creature * creature );
void command_equipment ( HWND window, const Creature * creature );
void command_wear ( HWND window, Creature * creature, char * string );
void command_remove ( HWND window, Creature * creature, char * string );
void command_attack ( HWND window, Creature * attacker, char * target );
void command_swap ( HWND window, Creature * creature );
void command_look ( HWND window, Room * room, Creature * player, char * string );
void command_health ( HWND window, Creature * player );

/* error.c */
void error ( const char * description, const char * file, int line );
void win_error ( const char * description, const char * file, int line );

/* main.c */
void initialize ( void );
void shut_down ( Creature * creature );

/* unsorted.c */
Creature * create_creature ( const char * name, double time_to_live );
Item * create_armor ( const char * name, const char * description );
Room * create_room ( const char * name, const char * description );
Spawn_Group * create_spawn_group ( const char * name, short max_spawns, double time_to_spawn, double time_to_live, float spawn_probability );
Creature * find_creature_in_room ( char * name, Room * room, short * ordinal );
Item * find_item_in_room ( char * name, Room * room, short * ordinal );
Item * find_item_in_hands ( char * name, Creature * creature, short * ordinal );
Item * find_item_in_inventory ( char * name, Item * inventory, short * ordinal );
double calculate_attack_speed ( HWND window, Creature * creature, Item * attacking_object, BOOL is_attacking_right_hand );
double calculate_chance_to_hit ( HWND window, Creature * creature, BOOL is_attacking_right_hand );
double calculate_chance_to_evade ( HWND window, const Creature * creature );
double calculate_chance_to_parry ( HWND window, const Creature * creature );
double calculate_chance_to_block ( HWND window, const Creature * creature );
double calculate_damage ( HWND window, const Creature * creature );
double calculate_damage_reduction ( HWND window, const Creature * creature );
short determine_ordinal ( char ** string );
float calculate_vitality ( Creature * creature );
void display_health ( HWND window, Creature * creature );
BOOL display_body_part_health ( HWND window, Creature * creature, const char * body_part, float value, int current_displayed_injuries, int number_injured_body_parts );
int get_number_of_injured_body_parts ( Creature * creature );
float get_weapon_skill ( Creature * creature, BOOL is_right_hand );



#endif
